{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "@题目1 手写汉字识别"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 处理数据集"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 先读入训练集txt，制作映射表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "tmp=[]\n",
    "with open('./data/HandWrite/HW_Chinese/train.txt','r') as f:\n",
    "    for lines in f:\n",
    "        if lines.startswith('\\n'):\n",
    "            continue\n",
    "        ib_idx=lines.index(' ')\n",
    "        s=lines[ib_idx:-1]\n",
    "        tmp.append(s[1:])\n",
    "sk=set()\n",
    "for i in tmp:\n",
    "    for c in i:\n",
    "        sk.add(c)\n",
    "one_hot=list(sk)\n",
    "ss=''\n",
    "for i in one_hot:\n",
    "    ss+=i\n",
    "with open('./data/ss1.txt','w') as f:\n",
    "    f.write(ss)\n",
    "    f.write('\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['线处失守边缘同花',\n",
       " '业发车补贴两千余',\n",
       " '从年审计署公布的',\n",
       " '障和改善民生的头',\n",
       " '开了一个洞当他',\n",
       " '工作规格般为副',\n",
       " '的情况授予安监',\n",
       " '库房用绳索和抬',\n",
       " '区复赛刚刚在上邦',\n",
       " '数今日的走势来看',\n",
       " '成本线已经处于失',\n",
       " '束机制不健全企业',\n",
       " '下调煤炭价格以应',\n",
       " '瓶可乐然后再找可',\n",
       " '美国运至广州港不',\n",
       " '关单数据为出口企',\n",
       " '流中心的天然基',\n",
       " '中间人再通过中间',\n",
       " '百分点一年期贷',\n",
       " '内中间人经查王挺',\n",
       " '个改革开放基础',\n",
       " '带动东北振兴武',\n",
       " '的同事早已完成万',\n",
       " '并未同其合作我们',\n",
       " '实需要他认为大连',\n",
       " '低贷款利率却同时',\n",
       " '的是前期搭着高油',\n",
       " '展高科技产业山西',\n",
       " '大牌银行多赚元中',\n",
       " '和李力连男岁中国',\n",
       " '新晋商新形象新境',\n",
       " '成比例与西方国家',\n",
       " '说事故原因目前正',\n",
       " '效应可能存在不愿',\n",
       " '补偿尚未开启的可',\n",
       " '的爱好这包括其管',\n",
       " '特别是现代犯罪',\n",
       " '心国泰基金表示昨',\n",
       " '有的同事早已完成',\n",
       " '主管出口企业出口',\n",
       " '学医疗中心照顾',\n",
       " '谢罪赔偿等横幅高',\n",
       " '对这起指控他矢',\n",
       " '难耐寂寞与站街女',\n",
       " '救援人员在戈壁腹',\n",
       " '职各守其岗上述安',\n",
       " '走她就死给他看男',\n",
       " '家添利博时裕祥长',\n",
       " '美国创新力上升欧',\n",
       " '四架口气很大袁',\n",
       " '口和龙头立足大',\n",
       " '公司重大资产重组',\n",
       " '前瞻性进一步增',\n",
       " '相对高位杀跌力',\n",
       " '内政部长马尔万等',\n",
       " '站的二期工程包',\n",
       " '以上述价格收购',\n",
       " '可能很快出现因此',\n",
       " '人民一定会记',\n",
       " '足够的放水空间然',\n",
       " '这样设计主要是',\n",
       " '产法修正案征求意',\n",
       " '存状态的汇丰采',\n",
       " '后别忘了参加专业',\n",
       " '大队副大队长刘会',\n",
       " '上周进行预披露创',\n",
       " '知道爆出来了这么',\n",
       " '物试行启运港退',\n",
       " '大臣等名大臣被',\n",
       " '近实在拖不下去了',\n",
       " '库尔尼科娃与男友',\n",
       " '少有人在本次风灾',\n",
       " '习惯庞思索了几',\n",
       " '排和环境保护发挥',\n",
       " '实在的刚才很多问',\n",
       " '行初步判定结论如',\n",
       " '库存在码头仓房堆',\n",
       " '次可上浮至基准利',\n",
       " '识别系统可核对身',\n",
       " '堪入目的手机短信',\n",
       " '和送欢乐下基层活',\n",
       " '汉市市容环境卫生',\n",
       " '罪嫌疑人缴获案',\n",
       " '五世及罗密欧与朱',\n",
       " '批的省级文保单',\n",
       " '电记者有之希腊',\n",
       " '错绝不道歉但这',\n",
       " '亚的访问前往约旦',\n",
       " '意料月日一名衣衫',\n",
       " '踩雷叶檀央行降息',\n",
       " '两难格局新华网上',\n",
       " '处对内是海陆联运',\n",
       " '活的追求武汉也渐',\n",
       " '警通过千里追踪数',\n",
       " '乏神通广大者小张',\n",
       " '主也有基金公司表',\n",
       " '经同意扩大人道',\n",
       " '食品样品万个检查',\n",
       " '成立专门调查委员',\n",
       " '火近距离枪击和',\n",
       " '鉴别他们的价值当',\n",
       " '流动性信托模式',\n",
       " '会调查了差不多两',\n",
       " '司预计月的工作日',\n",
       " '员戴着空气呼吸器',\n",
       " '建高尔夫球场的通',\n",
       " '类产品如国联安双',\n",
       " '家级新区将获得财',\n",
       " '警告讯号并组织周',\n",
       " '乌恰县日晚间发生',\n",
       " '对此江苏丰县顺',\n",
       " '十年国家发展改革',\n",
       " '青年油画家以其创',\n",
       " '日下边落款是河',\n",
       " '显然有点撑不住前',\n",
       " '此事重庆市房管局',\n",
       " '吁行业协会科研',\n",
       " '新力近年来胶南持',\n",
       " '客平台仅提供信息',\n",
       " '年月日上海浦东国',\n",
       " '劳务派遣人员的单',\n",
       " '圈而在十分钟的文',\n",
       " '公共服务基础设施',\n",
       " '的左文隶今年岁是',\n",
       " '多次受到支撑此',\n",
       " '报讯记者韩旭昨',\n",
       " '的武器叙利亚当局',\n",
       " '家上市公司重大资',\n",
       " '有雷阵雨其余市县',\n",
       " '客网总经理助理',\n",
       " '同事度更年期看尽',\n",
       " '来的超额收益方',\n",
       " '上的谣言如何处理',\n",
       " '昌在致词时表示马',\n",
       " '有采取合理措施处',\n",
       " '是说需要炒股的话',\n",
       " '表示目前宏观经济',\n",
       " '理和使用有关的规',\n",
       " '批准建设新的高尔',\n",
       " '怪异得多有大幅上',\n",
       " '行抢食市场蛋糕的',\n",
       " '大雨发生滑坡造成',\n",
       " '校设置个志愿专业',\n",
       " '要为基础设施和地',\n",
       " '点本周还将有英国',\n",
       " '对方一刀捅',\n",
       " '死后逃之案件',\n",
       " '须悲观年月份全国',\n",
       " '中国雅虎侠客平台',\n",
       " '来的不良后果当然',\n",
       " '购物区欧美阿联酋',\n",
       " '赞阶梯电价实现富',\n",
       " '的国民新党副代表',\n",
       " '消费为债务人减负',\n",
       " '不少申请旁听者而',\n",
       " '析人士表示大连如',\n",
       " '会给房地产市场带',\n",
       " '忠德本报通讯员',\n",
       " '生更大地震的可能',\n",
       " '日消息近日中美执',\n",
       " '警告日本读卖新闻',\n",
       " '客户过得遥自在',\n",
       " '宜获得有条件通过',\n",
       " '选基金吧四年多里',\n",
       " '与基准利率的背离',\n",
       " '头大连港位居西北',\n",
       " '下一步对融',\n",
       " '并组织周围米直径',\n",
       " '清晰记得月日市场',\n",
       " '业才是开发商的利',\n",
       " '退税政策货物若',\n",
       " '企业社会责任意识',\n",
       " '其中一男子将手里',\n",
       " '广大城乡居民分享',\n",
       " '公司再与用工单位',\n",
       " '不变相对货币市场',\n",
       " '年期定期存款利率',\n",
       " '阿拉伯板块正从',\n",
       " '友也辞去了法国国',\n",
       " '利亚供应战斗直升',\n",
       " '短期内有非对称降',\n",
       " '迪车车主何先生宁',\n",
       " '能再让土地空闲',\n",
       " '的意见下简称意见',\n",
       " '定存利率税后加',\n",
       " '二是政策层面国际',\n",
       " '跌以及国际板点',\n",
       " '的手脚链锁青年中',\n",
       " '与我国保险行业发',\n",
       " '定自年月日起下调',\n",
       " '元等中国奶牛养殖',\n",
       " '京蓝色港湾置业有',\n",
       " '累华宝油气前十大',\n",
       " '布置进入收尾阶段',\n",
       " '前陈桔元砸开了房',\n",
       " '吨而秦皇岛大卡煤',\n",
       " '风险投资者要对自',\n",
       " '生图为自治区人民',\n",
       " '雅虎侠客平台仅提',\n",
       " '买到所以不少市民',\n",
       " '建起来业界人士指',\n",
       " '贷计划食品添加剂',\n",
       " '得负债率高效率低',\n",
       " '家后有人故意做了',\n",
       " '公司同时承诺在未',\n",
       " '差异的不均衡性已',\n",
       " '渐分离这两个新板',\n",
       " '媒体工作她们有些',\n",
       " '作人员向记者证实',\n",
       " '上午三菱劳工索',\n",
       " '就形成了扩张融资',\n",
       " '直升机俄罗斯外交',\n",
       " '梯内挥拳打伤女医',\n",
       " '利亚霍姆斯哈马',\n",
       " '涨幅预期值在之',\n",
       " '比亚和俄罗斯的廉',\n",
       " '其实际收益就更',\n",
       " '别市县可能出现左',\n",
       " '所犯下的犯罪事实',\n",
       " '担心随着成交量',\n",
       " '谓是砸锅卖铁拉存',\n",
       " '下游饮水造成威胁',\n",
       " '存款和完成业绩任',\n",
       " '偿负面新闻传播很',\n",
       " '收益都在以上最高',\n",
       " '诉书内容情人节当',\n",
       " '门并进行现场文物',\n",
       " '期存款利息不降反',\n",
       " '道明天凌晨两场欧',\n",
       " '起捡钱分钱诈骗案',\n",
       " '析看一看艺',\n",
       " '此前的长期定存利',\n",
       " '及时解决医患纠纷',\n",
       " '内容均由上网用户',\n",
       " '全部被上面拿走了',\n",
       " '书面回复可乐瓶里',\n",
       " '暴起咬人全过',\n",
       " '法犯罪行为要果断',\n",
       " '在水和鹿肉中发现',\n",
       " '分的两支球队分别',\n",
       " '地方各级政府国务',\n",
       " '秀明星耶德古迪和',\n",
       " '仍将保持增长但增',\n",
       " '正是各行纷纷抬高',\n",
       " '与男友驾游艇出游',\n",
       " '及生命伤者中人中',\n",
       " '长向记者介绍他',\n",
       " '节能减排环境保',\n",
       " '般为副部级今年两',\n",
       " '设和运营为主营业',\n",
       " '停水停电停气渠城',\n",
       " '股建设银行万股同',\n",
       " '财有研究显示良好',\n",
       " '多名类似王挺的中',\n",
       " '害公众健康和安全',\n",
       " '梁先生拒绝其后梁',\n",
       " '元改扩建处农村文',\n",
       " '伯国家在土耳其伊',\n",
       " '初步判定结论如下',\n",
       " '板的北京英博电气',\n",
       " '控制与预防中心提',\n",
       " '台从而将潜在的中',\n",
       " '少年无钱治疗含泪',\n",
       " '档对困难群体给予',\n",
       " '另一同伙则在',\n",
       " '叙利亚主要反对组',\n",
       " '地发挥窗口作用国',\n",
       " '工行中行建行和汇',\n",
       " '局局长刘安成因为',\n",
       " '坡上有响声她立刻',\n",
       " '划和审批相关特殊',\n",
       " '个区域经社委员会',\n",
       " '捕民警分组前往淄',\n",
       " '难以见底但是通',\n",
       " '其职各守其岗上述',\n",
       " '高回报的项目可贷',\n",
       " '亿的艺术品成立于',\n",
       " '违法建设整治过程',\n",
       " '金凤镇的上邦国际',\n",
       " '外部宽松所带来的',\n",
       " '因成为公牺牲官方',\n",
       " '人都是无辜的路人',\n",
       " '为亿元万元亿元',\n",
       " '板方面南京宝色丹',\n",
       " '荣景象有业内人士',\n",
       " '月日下午时分许西',\n",
       " '对唱女生表现出',\n",
       " '困难群体给予定',\n",
       " '的石膏板产能布局',\n",
       " '资产关联交易方',\n",
       " '阶梯电价评述之',\n",
       " '川月日消息记者胡',\n",
       " '两层楼的库房大门',\n",
       " '中山站至冰断面',\n",
       " '短缺困境自从年初',\n",
       " '命并与在叙利亚国',\n",
       " '房贷月供减少元有',\n",
       " '已超过万人约万人',\n",
       " '的可乐朋友欲拿元',\n",
       " '企业先支付预付',\n",
       " '金等款项上述标的',\n",
       " '对驾驶者和其他',\n",
       " '电量增长有限南方',\n",
       " '收益率的可能性较',\n",
       " '不能在网络渠道购',\n",
       " '山群岛新区之后第',\n",
       " '医疗中心照顾名',\n",
       " '销人员有任务今年',\n",
       " '的各种沸沸扬扬大',\n",
       " '在与美国贸易商签',\n",
       " '意愿共同创建没有',\n",
       " '城市反哺农村体现',\n",
       " '一路走高中国海',\n",
       " '单位进行了量化评',\n",
       " '关人士表示从东北',\n",
       " '这一切程',\n",
       " '山西人从商历史悠',\n",
       " '就穿着白色比基尼',\n",
       " '以配合征求意见稿',\n",
       " '的宽松政策会对市',\n",
       " '负责安保的军官说',\n",
       " '邦文投资承担连带',\n",
       " '的现代化转型仅',\n",
       " '宣布日电价缓涨',\n",
       " '幅上升进口和出',\n",
       " '流露当被公诉人质',\n",
       " '股份有限公司在山',\n",
       " '使资金流出银行体',\n",
       " '规划部门是依据什',\n",
       " '些价值股也有定',\n",
       " '检部门的检验满',\n",
       " '居民阶梯电价听证',\n",
       " '痛哭北京时间今天',\n",
       " '供中国雅虎提示您',\n",
       " '重组中股票异常',\n",
       " '完成了整改其他问',\n",
       " '死因成为公牺牲官',\n",
       " '家属和陪护人员他',\n",
       " '投资方向运作模式',\n",
       " '响从上证指数今',\n",
       " '海关缉私局成立联',\n",
       " '经济与政策的来回',\n",
       " '份查处的每日经济',\n",
       " '但警方称已掌握嫌',\n",
       " '违反本社区规定而',\n",
       " '对于这样种种的矛',\n",
       " '装调试污水处理等',\n",
       " '国务院食安委的统',\n",
       " '的火电企业实行脱',\n",
       " '势是德国和丹麦分',\n",
       " '实施本报月日讯通',\n",
       " '续出现你认为基',\n",
       " '亡月日台湾考试院',\n",
       " '午梁先生将与可口',\n",
       " '行通过美牛案证所',\n",
       " '和保险资金启动增',\n",
       " '根据情况征集考生',\n",
       " '会立即将其遣返不',\n",
       " '召回事件日前日本',\n",
       " '攻基本上我国的煤',\n",
       " '市场利率较高的情',\n",
       " '日四大行已经对汇',\n",
       " '实习并于月日随公',\n",
       " '一中院门口始',\n",
       " '手绳之以法我们必',\n",
       " '对产生的后果负责',\n",
       " '一季度共有艺',\n",
       " '会太强按现行规定',\n",
       " '随后并没有进一',\n",
       " '分级管理工作根据',\n",
       " '股发行询价过程中',\n",
       " '可再生能源电价政',\n",
       " '上海洋山保税港区',\n",
       " '注焦点胡拉镇事件',\n",
       " '事务部贸易发展会',\n",
       " '男的还真敢死啊',\n",
       " '者硬币的价值只能',\n",
       " '色气体易燃易爆有',\n",
       " '的方式设置用钱的',\n",
       " '放根据招商证券',\n",
       " '相对薄弱的人群',\n",
       " '存款成为银行争夺',\n",
       " '市单价地王纪录该',\n",
       " '源紧缺以及由能源',\n",
       " '及时进行信息披露',\n",
       " '回的景象形成了鲜',\n",
       " '式进行扶持要坚持',\n",
       " '银行理财师私下',\n",
       " '增长率更明显低于',\n",
       " '统一规划',\n",
       " '域金融垄断程度高',\n",
       " '倍这不是天方夜谭',\n",
       " '达目的绝不罢休三',\n",
       " '型工具为主进行调',\n",
       " '屏幕上准时出现了',\n",
       " '降息深受大宗商品',\n",
       " '伤害而丧生其中包',\n",
       " '职年月日马尔代',\n",
       " '题银行圈钱发展模',\n",
       " '策因为刚需更加务',\n",
       " '为张绍刚存在自卑',\n",
       " '划向叙利亚万人提',\n",
       " '业创出个月以来的',\n",
       " '姐告诉记者其实',\n",
       " '中主要是省级平台',\n",
       " '东曲阜孔林附近女',\n",
       " '心师傅故意触碰胸',\n",
       " '们看到了攻打叙利',\n",
       " '定和等级公示宁夏',\n",
       " '部门依据职能分工',\n",
       " '用餐配送单位中央',\n",
       " '将非洲板块分为',\n",
       " '住了记者隔着教堂',\n",
       " '多市长罗布福特在',\n",
       " '过渡应该包括叙利',\n",
       " '日重周期行业表',\n",
       " '选举得以举行法国',\n",
       " '会正在加强与各',\n",
       " '沙河南岸风景',\n",
       " '明进行反驳指出',\n",
       " '图书馆等公共文化',\n",
       " '士表示大连设立国',\n",
       " '银行首套房贷利率',\n",
       " '大量的清洗工作',\n",
       " '人和爱国华侨的支',\n",
       " '至兴业银行首席经',\n",
       " '司和险资的持股成',\n",
       " '务业金融业石油开',\n",
       " '解便拿着手中的业',\n",
       " '月日上海老相机制',\n",
       " '是要坚持与国际',\n",
       " '渐近也标志着在',\n",
       " '企业发车补贴两千',\n",
       " '作为置出资产与中',\n",
       " '医院保持高度警戒',\n",
       " '台仅提供信息存',\n",
       " '正义的原则发改委',\n",
       " '居住需求外最主要',\n",
       " '国民警卫队参谋军',\n",
       " '案组迅速开展案件',\n",
       " '锣鼓等文化设施',\n",
       " '谋去年一场声势',\n",
       " '基本用电需求发挥',\n",
       " '精选基金吧混合基',\n",
       " '进党中央如何协助',\n",
       " '挑选难度在加大',\n",
       " '责任扎实推进量化',\n",
       " '维持经济增长不得',\n",
       " '效申购金额为亿元',\n",
       " '申报企业基本信息',\n",
       " '出探索建立到完善',\n",
       " '举行月日至日被确',\n",
       " '在大连设立国家级',\n",
       " '一开始上海',\n",
       " '物局列为河南省第',\n",
       " '人士认为随着货币',\n",
       " '唱成了红着但这恰',\n",
       " '质询不过由于陈冲',\n",
       " '路运输适用启运港',\n",
       " '英拉慰问月日在',\n",
       " '起咬人全过程中国',\n",
       " '组组当中两支传统',\n",
       " '全部货物进入离境',\n",
       " '径有专家表示由于',\n",
       " '基本促公平的制度',\n",
       " '耕种并垫付租金并',\n",
       " '者介绍他们之所以',\n",
       " '竟然允许开发商在',\n",
       " '太平洋面向世界的',\n",
       " '重大食品安全事故',\n",
       " '丰县顺河镇政府负',\n",
       " '能分工对使用政府',\n",
       " '索转变发展方式和',\n",
       " '些产品也可达到',\n",
       " '导致行政部门首长',\n",
       " '的不均衡性已经',\n",
       " '太仓一家宾馆还',\n",
       " '长城去年重新审核',\n",
       " '相关法律规定部',\n",
       " '计划对李旭利案的',\n",
       " '举得以举行法国还',\n",
       " '头整治的对象包',\n",
       " '利率走低经济回暖',\n",
       " '字里面挑刺然后',\n",
       " '关法律规定部分内',\n",
       " '汤灿被判年消息',\n",
       " '到这瓶可乐之后辗',\n",
       " '利亚供应直升机俄',\n",
       " '骨的变化袁纯清说',\n",
       " '公布一些构',\n",
       " '外走富玲说当时',\n",
       " '连分析人士表示',\n",
       " '极性减退甚至有港',\n",
       " '连经济和支柱产',\n",
       " '处于下行通道外围',\n",
       " '就被一抢而空',\n",
       " '最早出现的艺术品',\n",
       " '救护队的多名专业',\n",
       " '表示目前银行销售',\n",
       " '火力的武装分子目',\n",
       " '几厘米的水果刀',\n",
       " '地总建筑规模超',\n",
       " '水平保险市场发育',\n",
       " '故障停车图为发生',\n",
       " '捷的海上门户大连',\n",
       " '加高职单考单招的',\n",
       " '资成本刺激企业再',\n",
       " '存利率竟低至五年',\n",
       " '文通讯员陈佩云',\n",
       " '型文化广场加强市',\n",
       " '请点这里查看家中',\n",
       " '说别争了两期国债',\n",
       " '夺战三年定存利率',\n",
       " '问的水准层次不齐',\n",
       " '全宣传周活动由国',\n",
       " '而形成外部监管内',\n",
       " '证的小产权房全部',\n",
       " '关于居民阶梯电价',\n",
       " '息来源拉夫罗夫日',\n",
       " '权责一致的原',\n",
       " '了现在可谓是砸锅',\n",
       " '现场的警察和医护',\n",
       " '看清条款北新建材',\n",
       " '子的成长阶段而不',\n",
       " '经济体降息深受大',\n",
       " '大肠杆菌州扩散名',\n",
       " '的核心是法律和',\n",
       " '深感摸不着头脑长',\n",
       " '成为全国利率最优',\n",
       " '华夏银行的发行量',\n",
       " '刚才很多问题实际',\n",
       " '实际约定收益在之',\n",
       " '袭击万人受灾山东',\n",
       " '时规定申请成为常',\n",
       " '辆车牌号为赣的长',\n",
       " '叙利亚问题举行了',\n",
       " '果没有赚钱效应可',\n",
       " '加明显四大行目前',\n",
       " '并购重组委审核公',\n",
       " '监张大伟认为在',\n",
       " '娘打麻将不入洞房',\n",
       " '融机构人民币存贷',\n",
       " '实施意见详细规定',\n",
       " '显示去年美国大豆',\n",
       " '大连新市区位于东',\n",
       " '人提供援助月份',\n",
       " '重让国内煤炭企',\n",
       " '础资产的选择要兼',\n",
       " '媒体传出荷兰队出',\n",
       " '公司讲数梁先生问',\n",
       " '得再凶张绍刚也',\n",
       " '生山体滑塌事故月',\n",
       " '海关提供税务机关',\n",
       " '情后愿意以元的价',\n",
       " '下跌带来的净值损',\n",
       " '巴瘤于月日至月日',\n",
       " '食药监局工作部署',\n",
       " '出了规定种植环节',\n",
       " '刚的问题在于俯视',\n",
       " '约的比例但高于发',\n",
       " '项目价格上涨月平',\n",
       " '第远落后于日韩中',\n",
       " '闻中国雅虎侠客平',\n",
       " '公募基金领域年以',\n",
       " '暴露在风险之下',\n",
       " '佐治亚州例路易斯',\n",
       " '的质疑并不算大但',\n",
       " '治的对象包括年关',\n",
       " '目的申购新股的中',\n",
       " '南市珠海街道办事',\n",
       " '发现小强受伤昏',\n",
       " '里头但是一个',\n",
       " '枪商场内随后出',\n",
       " '逮捕了该案主犯现',\n",
       " '立足已有功能区设',\n",
       " '就是典型案例市场',\n",
       " '子上的内容就签了',\n",
       " '请折农业银行手',\n",
       " '华远地产股份有限',\n",
       " '查犯罪嫌疑人陈',\n",
       " '惯庞思索了几秒',\n",
       " '加强安全生产管',\n",
       " '主义援助万叙利',\n",
       " '门审批文物的保护',\n",
       " '场兴起时间不长部',\n",
       " '质饲料对华出口而',\n",
       " '优势并拥有相对需',\n",
       " '价值都一样认为',\n",
       " '的监控系统不但可',\n",
       " '为约定收益的支',\n",
       " '此在公安部和海关',\n",
       " '地方新疆地震局乌',\n",
       " '董事会于年月日审',\n",
       " '品安全需要社会各',\n",
       " '因非法侵入他人住',\n",
       " '银行的发行量居前',\n",
       " '力的武装分子目标',\n",
       " '委员会第一委员',\n",
       " '武献华提出了关于',\n",
       " '年期定存利率分别',\n",
       " '强烟台市政府日前',\n",
       " '专业高考进程月日',\n",
       " '相关院校信息专科',\n",
       " '对比可以看到投资',\n",
       " '帆布和警戒线围了',\n",
       " '是余彭年所拥有的',\n",
       " '每人吃了片被人发',\n",
       " '的理财习惯年龄金',\n",
       " '虎提示您尊重权利',\n",
       " '变国内煤炭的整体',\n",
       " '管理生态调查港',\n",
       " '上救市贷款基准利',\n",
       " '一定优势并',\n",
       " '微博称为宗盘',\n",
       " '放缓趋势上周仅',\n",
       " '业务实施细则征求',\n",
       " '中山西临汾仍然被',\n",
       " '经济在市场中我们',\n",
       " '作者余乐来源羊城',\n",
       " '起公诉后改变管辖',\n",
       " '安排国际金融组织',\n",
       " '付租金并将通过法',\n",
       " '听的人数达百余人',\n",
       " '证明三启运港退',\n",
       " '索行政区与功能区',\n",
       " '考试院长关中独生',\n",
       " '公布专科分数线月',\n",
       " '门附近拥堵的车',\n",
       " '昨日向多家有大批',\n",
       " '利率市场仅是探索',\n",
       " '普或许换位月日俄',\n",
       " '而分的如果再赢就',\n",
       " '线也在博物馆内重',\n",
       " '球迷来说今天晚上',\n",
       " '资讯成品油分析师',\n",
       " '放松的力度加大市',\n",
       " '升值为投资者带来',\n",
       " '套设施部分物业',\n",
       " '台贷计下降个基点',\n",
       " '强烈虽然据说输',\n",
       " '示从目前的银行信',\n",
       " '预叙利亚反对派',\n",
       " '上调出租车燃油附',\n",
       " '产品母基金投资类',\n",
       " '是用于国债政策性',\n",
       " '迅原唱的因为爱',\n",
       " '过平机会控告雇主',\n",
       " '落实国务院关于鼓',\n",
       " '北是我国面向东',\n",
       " '峻的国际经济环',\n",
       " '县人且该团伙人员',\n",
       " '发现乌木值百万当',\n",
       " '通知未予显示请点',\n",
       " '防阵雨图一位',\n",
       " '一体即将于',\n",
       " '年底或明年初进行',\n",
       " '行政负责人施政',\n",
       " '者的推荐工作建立',\n",
       " '法律规定部分内容',\n",
       " '月份全国居民消费',\n",
       " '未接电话过了几天',\n",
       " '别所有进入航天城',\n",
       " '鹏华丰泽债基基',\n",
       " '要向警方表达我的',\n",
       " '上报了额度申请但',\n",
       " '期的投资目前最受',\n",
       " '续第二个月降息累',\n",
       " '直批评医疗制度抨',\n",
       " '常生活渐行渐近也',\n",
       " '蚀作用最新朝鲜生',\n",
       " '行政部门首长提出',\n",
       " '荐类询价对象推荐',\n",
       " '少申请旁听者而实',\n",
       " '网络上疯传的则',\n",
       " '过仍维持在低位贸',\n",
       " '行银行员工倒苦',\n",
       " '规模恐慌加拿大',\n",
       " '不是报一个',\n",
       " '又一重要举措',\n",
       " '垣市长如此未雨绸',\n",
       " '内人士分析去年以',\n",
       " '外是东北亚地区国',\n",
       " '除去加大宣传力度',\n",
       " '即时解雇事主透过',\n",
       " '本论坛的主旨本社',\n",
       " '评级机构标准普',\n",
       " '预计降价幅度不会',\n",
       " '烟台市政府日前出',\n",
       " '非法枪爆物品活动',\n",
       " '结构比例符合中央',\n",
       " '金正恩为少年团代',\n",
       " '摄像头扫描读卡',\n",
       " '男子为逃脱遂将胡',\n",
       " '示月日上述四港煤',\n",
       " '有关在大连设立国',\n",
       " '记者目前大部分房',\n",
       " '咨询在研究报告中',\n",
       " '害公众健康和安',\n",
       " '思所想有问题的认',\n",
       " '业高考进程月日日',\n",
       " '时常吵架我就是想',\n",
       " '部的装布置进入',\n",
       " '同比涨幅进一',\n",
       " '现实需要他认为',\n",
       " '等待判决他失去自',\n",
       " '方向改革我国出租',\n",
       " '局长刘绍武介绍这',\n",
       " '见面平时各过各的',\n",
       " '代表大会代表资格',\n",
       " '方彻查枪源美方执',\n",
       " '负责审核二主要',\n",
       " '的岛屿管理生态调',\n",
       " '选人初步人选的',\n",
       " '装甲车卷起尘土前',\n",
       " '染上乙肝向生产商',\n",
       " '网月日消息据台湾',\n",
       " '基础管理建立长效',\n",
       " '依旧取得了很大成',\n",
       " '一个两难格局为',\n",
       " '在江苏扬州辽宁营',\n",
       " '次检出不合格进出',\n",
       " '元加上外汇占款可',\n",
       " '促公平这一',\n",
       " '开发的昌建外滩高',\n",
       " '点他指出不少售房',\n",
       " '中方渔政船曾次进',\n",
       " '就更多而根据标普',\n",
       " '第一枪平安银',\n",
       " '仓房堆积如山库存',\n",
       " '求多项数据料维持',\n",
       " '一枢纽的先行区',\n",
       " '下称雅盈堂实际',\n",
       " '行央行加大货币紧',\n",
       " '仅有几十万元的普',\n",
       " '的基本框架原则',\n",
       " '然发现高大的架桥',\n",
       " '渣打银行就要多得',\n",
       " '店会所等商品房和',\n",
       " '营企业的以上这',\n",
       " '无论是海外还是国',\n",
       " '日环食中国雅虎侠',\n",
       " '周末商场内至少聚',\n",
       " '注意的是分级债基',\n",
       " '用了约分钟你来晚',\n",
       " '发生级地震新疆',\n",
       " '不执行安全生产监',\n",
       " '运到广州港为元吨',\n",
       " '通宵麻将哪知第二',\n",
       " '卫生厅要求医疗机',\n",
       " '知未予显示请点这',\n",
       " '辉偿付能力监管体',\n",
       " '玻璃瓶可回收经清',\n",
       " '投资者望而却步征',\n",
       " '发现男子今年岁孩',\n",
       " '和使用中的违法行',\n",
       " '真地处理工作场所',\n",
       " '市将公共文化设施',\n",
       " '将食品安全工作列',\n",
       " '时指出我国民营企',\n",
       " '您尊重权利人之权',\n",
       " '叙利亚供应战斗直',\n",
       " '护和保障食品安全',\n",
       " '一步完善其制度',\n",
       " '有效报价或申购要',\n",
       " '还会做做鬼脸与父',\n",
       " '批的省级文保单位',\n",
       " '宣布幕剧院保存',\n",
       " '让议事再次陷入',\n",
       " '小产权房开绿灯无',\n",
       " '设厅评为拆迁管理',\n",
       " '房价的预期他还表',\n",
       " '友在迈阿密海边度',\n",
       " '统不但可随时与',\n",
       " '出这起拆迁的实',\n",
       " '我尊严劳工历史不',\n",
       " '行政院仍一意孤',\n",
       " '的新阶段迫切需要',\n",
       " '评价意见看中央企',\n",
       " '挑刺然后喝批判',\n",
       " '消息将湖南推向了',\n",
       " '去了法国国际广播',\n",
       " '条款北新建材及其',\n",
       " '民出门不妨带备雨',\n",
       " '家庭协会副秘书长',\n",
       " '府节省了万元的支',\n",
       " '是发改委今日文章',\n",
       " '钓鱼岛争端不断日',\n",
       " '重时不时地打土豪',\n",
       " '大众日报金正恩',\n",
       " '来有代表性的艺术',\n",
       " '善与市场经济相适',\n",
       " '内容在新股发行询',\n",
       " '行同比涨幅较上月',\n",
       " '的女司机迟到导',\n",
       " '旧金山月日电记者',\n",
       " '查看活跃在全球',\n",
       " '前还没有足够的事',\n",
       " '基发展迅速目前已',\n",
       " '品非法添加和滥',\n",
       " '家的不是银行的存',\n",
       " '司董事长黄宇杰由',\n",
       " '际合作的不断深化',\n",
       " '帮他请关注逃命到',\n",
       " '济与政策的来回博',\n",
       " '工地方已加紧抢',\n",
       " '海游玩时候的镜头',\n",
       " '业金融业石油开',\n",
       " '样这是为了你好而',\n",
       " '里查看法国第女',\n",
       " '时还需经党的第十',\n",
       " '收益率的可能性较',\n",
       " '的硬性要求银行必',\n",
       " '她一拳就跑医',\n",
       " '值股和成长股基本',\n",
       " '案在中国抓获犯罪',\n",
       " '个基点至这是该行',\n",
       " '升至历史高位从',\n",
       " '台公司贷款被明确',\n",
       " '人之权利根据相',\n",
       " '中行招行汇丰等大',\n",
       " '案不管是美牛或证',\n",
       " '卫生厅呼吁一',\n",
       " '制所以一般情下',\n",
       " '之权利根据相关',\n",
       " '着手中的业务单前',\n",
       " '钓鱼岛岛但被东京',\n",
       " '人对这起指控他',\n",
       " '振精神做时代的新',\n",
       " '万存款变保单退回',\n",
       " '这是为了你好而自',\n",
       " '太温情了孩子望着',\n",
       " '下来能挣万多元在',\n",
       " '行为代表的多家股',\n",
       " '霜袋里再拧紧盖子',\n",
       " '手与记者相握这是',\n",
       " '建筑物安全应立',\n",
       " '国内以及邻国迫切',\n",
       " '下同时申购单新',\n",
       " '况也很不乐观今年',\n",
       " '启运地口岸为青岛',\n",
       " '由于每个孩子的性',\n",
       " '林信托发行了款',\n",
       " '务总局研究制定四',\n",
       " '放眼东北亚随着国',\n",
       " '不多于名个人投资',\n",
       " '回信托份额增加了',\n",
       " '市场环境下很难说',\n",
       " '安邦咨询研究员从',\n",
       " '集开放期据统计在',\n",
       " '债但需谨慎考量风',\n",
       " '清楚上邦高尔夫球',\n",
       " '观的背景下反周期',\n",
       " '元的存款到期取钱',\n",
       " '的放映权古迪指示',\n",
       " '物价回落中金公司',\n",
       " '营销费用就会打折',\n",
       " '地震发生后新疆地',\n",
       " '门口前等候你已经',\n",
       " '经中国证监会并购',\n",
       " '动物价回落中金公',\n",
       " '融资担保和跟进投',\n",
       " '年所发生的新的经',\n",
       " '中途不能取回想取',\n",
       " '另一位护士',\n",
       " '困难群众基本生活',\n",
       " '气渠城滨河路龙溪',\n",
       " '吸引了超过亿元资',\n",
       " '影新京报记者郭铁',\n",
       " '以及其他风险较低',\n",
       " '加大责任追究力度',\n",
       " '西北太平洋中枢是',\n",
       " '书画作品雅昌艺术',\n",
       " '不同通过不同的亲',\n",
       " '至有港口出现空泊',\n",
       " '孩子看和讲有关购',\n",
       " '部联赛南方区复赛',\n",
       " '有的廊坊开发区新',\n",
       " '次受到支撑此次',\n",
       " '牌吸引消费者购买',\n",
       " '连平微博表示当前',\n",
       " '的情况尤为严重',\n",
       " '肝向生产商索赔万',\n",
       " '而行月日华润银行',\n",
       " '根弯曲的吸管这瓶',\n",
       " '里公共文化服务圈',\n",
       " '官网上回应了日前',\n",
       " '连设立国家级新',\n",
       " '车的前部凹进的车',\n",
       " '空间服务其内容均',\n",
       " '触犯中华人民共和',\n",
       " '安全监管力度努力',\n",
       " '国的失业率出现反',\n",
       " '引导积极探索开创',\n",
       " '货币紧缩力度导致',\n",
       " '重创股指一',\n",
       " '即将于近期开工',\n",
       " '土在前行车内三名',\n",
       " '企业将乐于把新增',\n",
       " '党将会强烈反应今',\n",
       " '直径范围内的上',\n",
       " '了全面落实他于今',\n",
       " '俄罗斯党代表大会',\n",
       " '法部门联手成功破',\n",
       " '明确了评定程序公',\n",
       " '的活期存款利率均',\n",
       " '示分级债基上涨',\n",
       " '假话不是说我有双',\n",
       " '由贸易区先行区的',\n",
       " '感染这种病菌这些',\n",
       " '个人投资者望而却',\n",
       " '队内和葡萄牙队',\n",
       " '件万起重新审核并',\n",
       " '医院保持高度警戒',\n",
       " '野党要求先为证所',\n",
       " '虎提示您尊重权利',\n",
       " '房需求的平稳释放',\n",
       " '供万个食品包裹月',\n",
       " '收到短信通知报考',\n",
       " '度避免由于各类关',\n",
       " '疑人缴获作案车',\n",
       " '铁娘子麦卡利斯年',\n",
       " '分析表明各国央行',\n",
       " '这种思想碰撞达到',\n",
       " '金公司增持四大行',\n",
       " '络进行犯罪交易隐',\n",
       " '能多达人其中理',\n",
       " '务院食安委的统',\n",
       " '党前主席蔡英文桃',\n",
       " '利根据相关法律',\n",
       " '可能是保管不当造',\n",
       " '至符合市场预期这',\n",
       " '突还会长期地存在',\n",
       " '移动的大肥皂装',\n",
       " '日向每日经济新闻',\n",
       " '方称已掌握嫌疑人',\n",
       " '推动份额的表现鹏',\n",
       " '银行理财产品销售',\n",
       " '莎士比亚剧院遗址',\n",
       " '孩子学习理财儿',\n",
       " '楼下负责放风随后',\n",
       " '试需要提醒考生的',\n",
       " '拿大个省份经营业',\n",
       " '同时按持股比例支',\n",
       " '限用农药和有毒有',\n",
       " '的装甲车代号一',\n",
       " '还是会继续回落伟',\n",
       " '专题讨论比如页',\n",
       " '国民党下周将强行',\n",
       " '油附加费其中北京',\n",
       " '一侧倒下时个',\n",
       " '个中心舞台外还建',\n",
       " '天自己却加仓的经',\n",
       " '次假冒警察逼迫被',\n",
       " '组网上民意汹汹',\n",
       " '案被警方破获中广',\n",
       " '上戴面纱她希望来',\n",
       " '量价齐升庞说在为',\n",
       " '赛刚刚在此落幕去',\n",
       " '交易方案获得中国',\n",
       " '个检查食品生产单',\n",
       " '权利人之权利根据',\n",
       " '线月日月日专科提',\n",
       " '季度的高位降至左',\n",
       " '的内容就签了名字',\n",
       " '二主要流程出口企',\n",
       " '面溃败甚至远低于',\n",
       " '各家银行发行的组',\n",
       " '没有个人利益的驱',\n",
       " '的核心是法律和',\n",
       " '监督量化分级管理',\n",
       " '面向东北亚开合',\n",
       " '亿元计划主要为大',\n",
       " '激动开始谩骂侮辱',\n",
       " '胡师傅随后被送',\n",
       " '有工作人员介绍但',\n",
       " '证券公司下发了首',\n",
       " '结目前国内外煤价',\n",
       " '报道法国新任总统',\n",
       " '监会并购重组委审',\n",
       " '年月日调查逾十月',\n",
       " '涉嫌贪污更改为滥',\n",
       " '没想到他说着说着',\n",
       " '果就震荡所以绝对',\n",
       " '坚持市场化运作通',\n",
       " '主义援助走婚族悄',\n",
       " '调查发现目前各家',\n",
       " '监部门作出的停产',\n",
       " '药残留中央厨房卫',\n",
       " '及相关材料到主管',\n",
       " '据本周陆续公布',\n",
       " '难的事情因为它既',\n",
       " '妻子今年月在上海',\n",
       " '华社记者刘雪据新',\n",
       " '业课考试时间有',\n",
       " '从目前市场成交结',\n",
       " '多少定义添加剂的',\n",
       " '是时候我只是她',\n",
       " '的视角去寻找投资',\n",
       " '吗民警立刻赶到现',\n",
       " '干来源中国新闻网',\n",
       " ...]"
      ]
     },
     "execution_count": 98,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tmp #预览训练集标签"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "with open('./data/ss1.txt','r') as f:\n",
    "    one_hot=f.readline()\n",
    "one_hot=one_hot[:-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'底呈奇申月究直遗邱康另情翁避普熊沟鲍此扶捏没何播矛生详阶隙辨拟山渠辈闸哭盛泪块拍惋建鉴干代凤怪结迫椎棚彭垣澳赖抬画肉动照类栋泉截开浓皆尖板郭植某筹木桃呼抄置培悦吹滚吐磋圈凌夺场笼们挣拨献穷留衍构驳坡孤众衰筑欲沙综钻担瑶妻报遥辩壮扛城斩米妮教肝曝训抵车易遣惊滥如范消哥亢酬休蔬冤独打凶忠手瞻被评女传亿内币汇哗溃侯看研碌充版剂拉摩试孜皮晴搬僵轨堵即义往羽戒思逼朝铭赞鹏筒十纳胡薪赂言狙碗功跌编装猛收酿悬宝涛域册源少角罗劳航尺光位恶首制婿浪弥歉增弹领昭袋柜起抓陈束凳拧邮忙摊佐刚减硬进漳淘里端毒虽线猎催无剧序空粤霉绪索澄份声宿展宫北占规锦管吧擦岸顾压轻贵怀键拾快平峻桂纸威虑左逊妙灌临希惑它霍势侦疆贺侠京印霜厨初屿备冰液于朗撤方害案哺脸书兑分舍锁视茨千游辐桶便授核辛誉粹简青怒疑阜烈慈悔峰忧司亡侧持齐延死绝挖函士谩八驼履几终牌熟拓时狠坍衔津墩掀支造嗽拆达命桥厘屡衅劝贴维喜陶现油棺龙冉敲晰夷助林阳借堂境堆上地配骤个良适电骂价味循翼存胆灰乏条潮深词斑酒贝隔旗冀音删替件睁影王储致家旧座顿泽企盾摘冻及歪毁考称缮昨朴治庆经仓违恢寻既西李弗敛滩盲柴停史煮喉蹲到誓形勇谅悍爱帮繁好网钓垄苦校按撼箭河贿仙议恰牵职裸鱼谴乌侵迹难殷土了谣搜季么曲为胸剖颜扩亦购膨民换川缺著彰晨吓肩限莲部络触店包眼蹈护且幕技卫掉文斤葛惟凭带丈硝袭钞惨贷蛇慧袖嘲火中挑边摆纵那弱户策荡变闽固脂薛县未亲耳脱横冲揽竞岳牲亥昆标涌馆贸恋则融骨珠灼龄由始铃泥波泊些鲜瞧退善实小华艾捕因狼风太硫甚株朱滞陆怕恤比撞州指作乙攻肤喝湘偏低刺郡浴腹韦蹭枝咳址曾托四苏图参释廷排病厉坞卑划邵测请趴酱惯牛竟德伸姓梁概届满恩壳甲跪朋菌珍同熔多兄庚跨疼霓疯胁防又吊门冒乳靠税谨坦付修惜柔尘暂元双盟桌讶洋惩峡以亚敢蒋夹目奥帖片景更并滨孔呕抽举侨还姑郸莫象罕盈丛绕塞涉谁享扎重辉渺井答信吨悲据檀待监艇裂荣突介汕妨窗射精涂寿溪见豪室梨霞卢师狱碍毕球堡沂绩徐偷穿坐棒樊数斌吻缴寨色填等战式集缠粉雅贪辖挡神服浩奶社像允余拳挪饱布欧热屏廖导坛望做疲坏连立工卡床慢勿险拦居科邢爹琴裕劣斜臭默卜野缅理炒戏离化从取吉洗界肥聚掺毗央型归约而券守章颇庞阴楼秃墨度敏坠弟却回择丁选探批搏频抱呢晚员添尤翔量骄差拔水谋驱踪裤这鸟提夏相溯盆荒异越墙慰识辣夕认张渝道胀绑货果倾宣徽出糕官诈摸牧统侮躺政透援麦承具富馈孟逾然真矿匪焉摇群晓匿遭武孕市秽忘随焕派童求品啤句帝磺倍是骗路诚唯邻钱历刷母明姆整彻仔哑俱断泛花府尊甜炼宇雪街层淋杠放彦疫招许封跑埋陋口寸鲁讲捷改毯陨复埃录幸艰耐尔映柯锐阵惠宾雇用语枯狈袁吗念蓄喀广竭发距属督遂私房安在辽窜爆渐公赌佳怨秦气抢处瑞灾嚼瞬况事辅次候傲粗旨已皇右才下礼亮专鸿伞优罐仅所钠沈暴聊桩矢贫勤阿沉来链绍听镇半调岛眠毫殖坊畴剩襄陕尚足栏奔马英证采氛钟奠描浦劲傻凑斡瘤蚀示冯乃逗铆心啥倘囊关前盘微泻脊析狐奎扫宏折素虚益焦远纽哄潘芋遏砖揭泰废予权媒环糊榨削物若岩伴扬诱汉逮纯巧隆续洪渡节湖贯闻健腾陇贡谊傍百蛋墅早党叫趋迷长皂俩旦洼大设餐云烟淤营肾寂坝戴尾染他星锣需互救娱摄贞不伍奢辱绘莎署嘉缘格子昌厦转和孩过白友肿狂玻溢债腊行措汰写挫促殿符捶赵鼓架盐杰掩坑凹向移什振贩垫础勘赔蜜甩橙曹恒副您杯仰依郊商系例原级梅挂程啦伊售较腕轰氨审杀暖炉仇法寄貌亏辞鹿假咱炸梯与韩联帅菜班械醒董耗一扮止活清忍铁丧拒住给库机旅严捅榔财森暗身肋字黄困铸搭绸帆新忆骆误胶强潜萄劫妓闲鬼邀苯谓乡肃鲸旺永姜掖单队逐牢汾沸拘征庭篇碎育掘柱籍别晕附逃村各徘挺五衣梦爷论巢叹纱徊兰肚软贬危刀秀料警捧略鼻克咬久落掌逆共途沾歧辗浙荐负唱走读婴迅欣计瘫契围枚玉芯肠陪短缝逻斥妈汗区腐洛浇银福塔团喷赁番的轮成错垮怖尽彼驻圆腔腰励推近叙外洲愤年混讨挟薄非雷耸召葬款后伦先办器想廊披页谷之茅丽会纷爬芬今粮踏纪弯常脚两兵擅丹沪茶送扣晤体阁冬棍密润癌淫汹膏点笑争烫判值秩萌国巴拥幅溜扇庄站岁乱轿课叶旬膜宴拎抑切感旁仍食稀妹侈症补炮兴藏挥徒追摧费业档伟荷父赛隐仑也遇黑衡检抗桑寞洞租都尸验楚吕凸掏票赣烧号艺喘迟登船海学径吸顽斗模汽智自表患辰美利赫损昏骇均壁根吴使燃遵淡日亨引丑革术渣递辆绳呵观耕囤陷潭偶吁仁高裹遍捐息污列伤迈淹但覆载敌漫斯该秒饲吵菱姐产饭刻南甸草可正返勒稍赴悠步古瘪怎锋抛宽蒲估再细牺秘漠蔽期猜渔粘养盗责谭绒赠男苹资疾藉周或继扰殴故输找耀访算俗般台胖汛忽任薯儿迁鸥态力蓝酋鸡质钢超缩趁奖弘碰当觉擎头控坪戮绿局傅操宵显顶插积第沿春军凯苑柏闯榜天芦容意悉蒙砸氏拼喊洒泄睡桔葡宅露汤账骚豆屁东淄咨萨诺激宜港升特捡杨戚纺佩让澈驾卖兼毛酸厌疗接刊协犯胜必律枢框玄灯降橱记疏将堪璃涵肖蔡镜耶种否巡状翻跟谐丝堤踢乔震览沃哈摔委诉典裁院组椅旭哲破崩面辜郑盼我石浮彩间镑演罩诸祖闷障散鼠似猪宙习浑至缓饼迪九宗慎背甘阻幼名胺杆崖其老启问佛娘隶含脑响赚套速合宪凡跳者愈稳饮很告梳痕察雨遮效稿婆烹话歌裴应岗残孙泼洁样令垂滑她奈完田吃彪杂施轴裔嘴二温啸就婚锈入穆人巨决材艳去注哀刘耻嫩拿股零塌迎渤殊炙订趣莱乘欢罚有祥呛卷谈剐晋世奋败伯抨戈击醉胃际飞说夯能受孝黎揍销牙瓶仪痪总基客要羊拢踩窖敦全玩卓顺倒雏虹妥恐预询握盖盒签宁交梭割知荆织携赎倚药拖午牟刑香菏段缉主谱衫鸣乐俯莉驶枪麻获每执只通讽厅押笔雾你反急涨箱把霄伐厕保漏邯钩肯率本得罢万创净萎挨愿募宋阅禁虎嫁博医血卿够述投除夫搞丰准燕屋赋烂挤金蒂嫌畏灿着省冈赶供耘稽柳买娜瞩失农灵攀罪冷七懂拐志解赢题蔓浆乎邦骑锅园谢额确厂夜江姻席畜炭跃晒性池闭瘦郎扯项痛瓦瑟济撑仿对魏免胎尼坚务须弄钾煤流族松舟鹤妇努廉哪己紧娃菲运臣弃查加最舞针括定膀码旋红憾亩偿极悄六伙讯末三玲慌树湾淀唐俄纠叉累练啊'"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "one_hot #预览2300个种类的字"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 对长图片进行投影法切片"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [],
   "source": [
    "%mkdir /home/asd/data/train_img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "import numpy as np\n",
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "#切片函数\n",
    "def crop(b,begin_idx):\n",
    "    for i in range(begin_idx,len(b)):\n",
    "        if b[i]==0:\n",
    "            continue\n",
    "        else:\n",
    "            begin_idx=max(i-1,begin_idx)\n",
    "            break\n",
    "    end_idx=begin_idx\n",
    "    for i in range(begin_idx,len(b)-10):\n",
    "        tmp=0\n",
    "        for j in range(i,i+7):\n",
    "            tmp+=b[j]\n",
    "        if tmp==0:\n",
    "            end_idx=i\n",
    "            break\n",
    "    return begin_idx,end_idx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 30min 23s, sys: 3min 29s, total: 33min 53s\n",
      "Wall time: 33min 58s\n"
     ]
    }
   ],
   "source": [
    "#对20万张图片进行切片，并将切片好的图分别存放到对应类别中\n",
    "%%time\n",
    "for i in range(0,200000):\n",
    "    path='./data/HandWrite/HW_Chinese/train_data/'+str(i)+'.png'\n",
    "    img=Image.open(path).convert('1')\n",
    "    img_arr=np.array(img)\n",
    "    img_arr=1-img_arr\n",
    "    a=torch.tensor(img_arr)\n",
    "    b=a.sum(dim=0)\n",
    "    crops=[]\n",
    "    b_idx=0\n",
    "    e_idx=len(b)\n",
    "    img=Image.open(path)\n",
    "    while(True):\n",
    "        b_idx,e_idx=crop(b,b_idx)\n",
    "        if e_idx-b_idx<=10:\n",
    "            break\n",
    "        crops.append([b_idx,e_idx])\n",
    "        b_idx=e_idx\n",
    "    p=[]\n",
    "    for j in crops:\n",
    "        box = (j[0],0,j[1],32)\n",
    "        img_new = img.crop(box)\n",
    "        p.append(img_new)\n",
    "    ss=tmp[i]\n",
    "    this_len=len(p)\n",
    "    if not this_len==len(ss):\n",
    "        continue\n",
    "    for k in range(this_len):\n",
    "        char_c=ss[k]\n",
    "        num_idx=one_hot.find(char_c)\n",
    "        if not os.path.exists('./data/train_img/'+str(num_idx)):\n",
    "            os.mkdir('./data/train_img/'+str(num_idx))\n",
    "        png_num=len(os.listdir('./data/train_img/'+str(num_idx)))\n",
    "        map_data = np.array(p[k].convert('RGB'))\n",
    "        map_data = np.asarray(map_data, np.uint8)\n",
    "        pic = Image.fromarray(map_data)\n",
    "        pic.save('./data/train_img/'+str(num_idx)+'/'+str(png_num)+'.png')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "切片文件总数:\n",
      "601345\n"
     ]
    }
   ],
   "source": [
    "print('切片文件总数:')\n",
    "!find ./h_data/ -type f | wc -l"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 对切片进行数据增强"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image, ImageChops\n",
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "#定义平移方法\n",
    "def ImgOfffSet(Img,xoff,yoff):\n",
    "    width, height = Img.size\n",
    "    c = ImageChops.offset(Img,xoff,yoff)\n",
    "    c.paste((255,255,255),(0,0,xoff,height))\n",
    "    c.paste((255,255,255),(0,0,width,yoff))\n",
    "    return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [],
   "source": [
    "#对图片进行随机小幅度平移和旋转，补齐数据\n",
    "mlen=len(os.listdir('./data/train_img/'))\n",
    "for i in range(0,mlen):\n",
    "    num=len(os.listdir('./data/train_img/'+str(i)))\n",
    "    back=num\n",
    "    while(num<100):\n",
    "        r_idx=random.randint(0,back-1)\n",
    "        img=Image.open('./data/train_img/'+str(i)+'/'+str(r_idx)+'.png')\n",
    "        xoff=random.randint(-2,2)\n",
    "        yoff=random.randint(-2,2)\n",
    "#         deg=30*random.random()-15\n",
    "#         img = img.rotate(deg)\n",
    "        img=ImgOfffSet(img,xoff,yoff)\n",
    "        png_num=len(os.listdir('./data/train_img/'+str(i)))\n",
    "        img.save('./data/train_img/'+str(i)+'/'+str(png_num)+'.png')\n",
    "        num+=1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 构建DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import numpy as np\n",
    "from PIL import Image\n",
    "from torch.utils import data\n",
    "import os"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 读取总类别数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2299\n"
     ]
    }
   ],
   "source": [
    "#类别总数\n",
    "all_kinds=len(one_hot)\n",
    "print(all_kinds)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构建myDataset类继承DataSet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "class myDataset(data.Dataset):\n",
    "    def __init__(self,x,y):\n",
    "        #创建5*2的数据集\n",
    "        self.data = x\n",
    "        #5个数据的标签\n",
    "        self.label = y\n",
    "    #根据索引获取data和label\n",
    "    def __getitem__(self,index):\n",
    "        return self.data[index], self.label[index] #以元组的形式返回\n",
    "\n",
    "    #获取数据集的大小\n",
    "    def __len__(self):\n",
    "        return len(self.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import ImageFilter"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 获取图片，加载训练集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [],
   "source": [
    "#获取长度为100的图片\n",
    "def get_df_data(all_kinds):\n",
    "    source=[]\n",
    "    y_train=[]\n",
    "    mlen=len(os.listdir('./data/train_img/'))\n",
    "    for i in range(mlen):\n",
    "        tlen=len(os.listdir('./data/train_img/'+str(i)))\n",
    "        if tlen>100:\n",
    "            continue\n",
    "        for j in range(0,100):\n",
    "            img=Image.open('./data/train_img/'+str(i)+'/'+str(j)+'.png').resize([64,64]).convert('L')\n",
    "            img = img.filter(ImageFilter.SHARPEN)\n",
    "            source.append(np.array(img))\n",
    "            temp=np.zeros([1,all_kinds])\n",
    "            temp[0,i]=1\n",
    "            y_train.append(temp)\n",
    "    x=np.array(source)\n",
    "    del source\n",
    "    y=np.array(y_train)\n",
    "    del y_train\n",
    "    y=y.reshape(-1,all_kinds)\n",
    "    train_features = torch.tensor(x, dtype=torch.float32)\n",
    "    del x\n",
    "    train_labels=torch.tensor(y, dtype=torch.float32)\n",
    "    del y\n",
    "    train_features.unsqueeze_(dim=1)\n",
    "    train_data=myDataset(train_features,train_labels)\n",
    "    return train_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(torch.Size([229900, 1, 64, 64]), torch.Size([229900, 2299]))"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data=get_data(0,all_kinds)\n",
    "train_data.data.shape,train_data.label.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "ll=get_df_data(all_kinds)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "596.1919831223629"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.mean(ll)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(torch.Size([135100, 1, 64, 64]), torch.Size([135100, 2299]))"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_data=get_df_data(all_kinds)\n",
    "train_data.data.shape,train_data.label.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "#构建分组器\n",
    "batch_size=1100\n",
    "train_loader=data.DataLoader(train_data,batch_size=batch_size,shuffle=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 构建Res-Net 18模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ResNet18网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "from torch.nn import functional as F\n",
    "\n",
    "\n",
    "class ResNetBasicBlock(nn.Module):\n",
    "    def __init__(self, in_channels, out_channels, stride):\n",
    "        super(ResNetBasicBlock, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1)\n",
    "        self.bn1 = nn.BatchNorm2d(out_channels)\n",
    "        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride, padding=1)\n",
    "        self.bn2 = nn.BatchNorm2d(out_channels)\n",
    "\n",
    "    def forward(self, x):\n",
    "        output = self.conv1(x)\n",
    "        output = F.relu(self.bn1(output))\n",
    "        output = self.conv2(output)\n",
    "        output = self.bn2(output)\n",
    "        return F.relu(x + output)\n",
    "\n",
    "\n",
    "class ResNetDownBlock(nn.Module):\n",
    "    def __init__(self, in_channels, out_channels, stride):\n",
    "        super(ResNetDownBlock, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride[0], padding=1)\n",
    "        self.bn1 = nn.BatchNorm2d(out_channels)\n",
    "        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=stride[1], padding=1)\n",
    "        self.bn2 = nn.BatchNorm2d(out_channels)\n",
    "        self.extra = nn.Sequential(\n",
    "            nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride[0], padding=0),\n",
    "            nn.BatchNorm2d(out_channels)\n",
    "        )\n",
    "\n",
    "    def forward(self, x):\n",
    "        extra_x = self.extra(x)\n",
    "        output = self.conv1(x)\n",
    "        out = F.relu(self.bn1(output))\n",
    "\n",
    "        out = self.conv2(out)\n",
    "        out = self.bn2(out)\n",
    "        return F.relu(extra_x + out)\n",
    "\n",
    "\n",
    "class ResNet18(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(ResNet18, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3)\n",
    "        self.bn1 = nn.BatchNorm2d(64)\n",
    "        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n",
    "\n",
    "        self.layer1 = nn.Sequential(ResNetBasicBlock(64, 64, 1),\n",
    "                                    ResNetBasicBlock(64, 64, 1))\n",
    "\n",
    "        self.layer2 = nn.Sequential(ResNetDownBlock(64, 128, [2, 1]),\n",
    "                                    ResNetBasicBlock(128, 128, 1))\n",
    "\n",
    "        self.layer3 = nn.Sequential(ResNetDownBlock(128, 256, [2, 1]),\n",
    "                                    ResNetBasicBlock(256, 256, 1))\n",
    "\n",
    "        self.layer4 = nn.Sequential(ResNetDownBlock(256, 512, [2, 1]),\n",
    "                                    ResNetBasicBlock(512, 512, 1))\n",
    "\n",
    "        self.avgpool = nn.AdaptiveAvgPool2d(output_size=(1, 1))\n",
    "\n",
    "        self.fc = nn.Linear(512,all_kinds)\n",
    "\n",
    "    def forward(self, x):\n",
    "        out = self.conv1(x)\n",
    "        out = self.layer1(out)\n",
    "        out = self.layer2(out)\n",
    "        out = self.layer3(out)\n",
    "        out = self.layer4(out)\n",
    "        out = self.avgpool(out)\n",
    "        out = out.reshape(x.shape[0], -1)\n",
    "        out = self.fc(out)\n",
    "        return out"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 实例化模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 使用GPU进行模型训练\n",
    "dev=torch.device('cuda:0')\n",
    "net=ResNet18()\n",
    "net=net.to(dev)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([1, 2299])"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "net(X[0].to(dev)).shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 创建交叉熵损失函数和Adam优化器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "loss=torch.nn.CrossEntropyLoss()\n",
    "loss=loss.to(dev)\n",
    "optimizer=torch.optim.Adam(net.parameters(),lr=0.001)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 编写ACC计算函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [],
   "source": [
    "def acc(y_pre,y):\n",
    "    all=torch.sum(torch.argmax(y_pred,dim=1)==torch.argmax(y,dim=1))\n",
    "    return all/y.shape[0]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%time\n",
    "# net.train()\n",
    "# batch_size=200\n",
    "# for ii in range(5):\n",
    "#     train_data=get_data(ii,all_kinds)\n",
    "#     train_data.data.shape,train_data.label.shape\n",
    "#     train_loader=data.DataLoader(train_data,batch_size=batch_size,shuffle=True)\n",
    "for epoch in range(30):\n",
    "    for step,(X,y) in enumerate(train_loader):\n",
    "        X=X.to(dev)\n",
    "        y=y.to(dev)\n",
    "        y_pred=net(X)\n",
    "        optimizer.zero_grad()\n",
    "        cost=loss(y_pred,y)\n",
    "        cost.backward()\n",
    "        optimizer.step()\n",
    "        if step%50000==0:\n",
    "            print('epoch:',epoch,'loss',cost.to(torch.device('cpu')))\n",
    "            with torch.no_grad():\n",
    "                print('acc:',acc(y_pred,y))\n",
    "    if epoch%5==0 and epoch!=0:\n",
    "        net.eval()\n",
    "        with torch.no_grad():\n",
    "            net=net.to(torch.device('cpu'))\n",
    "            test(net)\n",
    "        net=net.to(dev)\n",
    "        net.train()\n",
    "torch.save(net.state_dict(), \"./data/model-resnet.pkl\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 验证模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "def test(net):\n",
    "    tmp=[]\n",
    "    net.eval()\n",
    "    a_sum=0\n",
    "    real_num=0\n",
    "    with open('./data/HandWrite/HW_Chinese/test.txt','r') as f:\n",
    "        for lines in f:\n",
    "            if lines.startswith('\\n'):\n",
    "                continue\n",
    "            ib_idx=lines.index(' ')\n",
    "            s=lines[ib_idx:-1]\n",
    "            tmp.append(s[1:])\n",
    "    #x_s=random.randint(0,10)\n",
    "    for i in range(0,10000):\n",
    "        t_a=0\n",
    "        t_r=0\n",
    "        path='./data/HandWrite/HW_Chinese/test_data/'+str(i)+'.png'\n",
    "        img=Image.open(path).convert('1')\n",
    "        img_arr=np.array(img)\n",
    "        img_arr=1-img_arr\n",
    "        a=torch.tensor(img_arr)\n",
    "        b=a.sum(dim=0)\n",
    "        crops=[]\n",
    "        b_idx=0\n",
    "        e_idx=len(b)\n",
    "        img=Image.open(path).convert('L')\n",
    "        img = img.filter(ImageFilter.SHARPEN)\n",
    "        while(True):\n",
    "            b_idx,e_idx=crop(b,b_idx)\n",
    "            if e_idx-b_idx<=6:\n",
    "                crops.append([e_idx,len(b)])\n",
    "                b_idx=e_idx\n",
    "                break\n",
    "            crops.append([b_idx,e_idx])\n",
    "            b_idx=e_idx\n",
    "        p=[]\n",
    "        for j in crops:\n",
    "            box = (j[0],0,j[1],32)\n",
    "            img_new = img.crop(box).resize([64,64])\n",
    "            backb=img_new\n",
    "            img_new=np.array(img_new)\n",
    "            img_new=torch.tensor(img_new,dtype=torch.float32)\n",
    "            y_pred=net(img_new.reshape([1,1,64,64]))\n",
    "            p.append(torch.argmax(y_pred))\n",
    "        #img.show()\n",
    "        ans=''\n",
    "        for nn,aa in enumerate(p):\n",
    "            ans+=one_hot[aa]\n",
    "            real_num+=1\n",
    "            if(nn>=len(tmp[i])):\n",
    "                break\n",
    "            if one_hot[aa]==tmp[i][nn]:\n",
    "                a_sum+=1\n",
    "                t_a+=1\n",
    "            t_r+=1\n",
    "#         print(tmp[i])\n",
    "#         print(ans)\n",
    "#         print('h',t_a/t_r)\n",
    "    print('test acc:',a_sum/real_num)\n",
    "    #print(real_num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test acc: 0.8516089746592346\n"
     ]
    }
   ],
   "source": [
    "new_model=ResNet18()\n",
    "new_model.load_state_dict(torch.load(\"./data/model-resnet.pkl\"))    # 加载模型参数     \n",
    "test(new_model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 显示分割效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "#The line above is necesary to show Matplotlib's plots inside a Jupyter Notebook\n",
    "\n",
    "import cv2\n",
    "from matplotlib import pyplot as plt\n",
    "import numpy as np\n",
    "def accessPiexl(img):\n",
    "    height = img.shape[0]\n",
    "    width = img.shape[1]\n",
    "    for i in range(height):\n",
    "       for j in range(width):\n",
    "           img[i][j] = 255 - img[i][j]\n",
    "    return img\n",
    "\n",
    "# 反相二值化图像\n",
    "def accessBinary(img, threshold=128):\n",
    "    img = accessPiexl(img)\n",
    "    # 边缘膨胀\n",
    "    kernel = np.ones((3, 3), np.uint8)\n",
    "    img = cv2.dilate(img, kernel, iterations=1)\n",
    "    _, img = cv2.threshold(img, threshold, 0, cv2.THRESH_TOZERO)\n",
    "    return img\n",
    "def showResults(path, borders, results=None):\n",
    "    img = cv2.imread(path)\n",
    "    # 绘制\n",
    "    print(img.shape)\n",
    "    for i, border in enumerate(borders):\n",
    "        cv2.rectangle(img, border[0], border[1], (0, 0, 255))\n",
    "        if results:\n",
    "            cv2.putText(img, str(results[i]), border[0], cv2.FONT_HERSHEY_COMPLEX, 0.8, (0, 255, 0), 1)\n",
    "        #cv2.circle(img, border[0], 1, (0, 255, 0), 0)\n",
    "    plt.imshow(img)\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[(243, 21), (266, 28)], [(185, 21), (194, 28)], [(249, 12), (263, 17)], [(67, 11), (83, 24)], [(101, 10), (120, 27)], [(145, 9), (153, 17)], [(6, 8), (19, 23)], [(177, 4), (196, 26)], [(61, 4), (67, 28)], [(247, 3), (263, 7)], [(211, 2), (226, 25)], [(6, 1), (15, 14)]]\n",
      "(32, 280, 3)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 寻找边缘，返回边框的左上角和右下角（利用cv2.findContours）\n",
    "def findBorderContours(path, maxArea=55):\n",
    "    img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)\n",
    "    img = accessBinary(img)\n",
    "    \n",
    "    contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n",
    "    borders = []\n",
    "    for contour in contours:\n",
    "        # 将边缘拟合成一个边框\n",
    "        x, y, w, h = cv2.boundingRect(contour)\n",
    "        if w*h > maxArea:\n",
    "            border = [(x, y), (x+w, y+h)]\n",
    "            borders.append(border)\n",
    "    return borders\n",
    "    \n",
    "path = './data/HandWrite/HW_Chinese/test_data/0.png'\n",
    "borders = findBorderContours(path)\n",
    "print(borders)\n",
    "showResults(path, borders)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(32, 280, 3)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def extractPeek(array_vals, min_vals=20, min_rect=20):\n",
    "    extrackPoints = []\n",
    "    startPoint = None\n",
    "    endPoint = None\n",
    "    for i, point in enumerate(array_vals):\n",
    "        if point > min_vals and startPoint == None:\n",
    "            startPoint = i\n",
    "        elif point < min_vals and startPoint != None:\n",
    "            endPoint = i\n",
    "\n",
    "        if startPoint != None and endPoint != None:\n",
    "            extrackPoints.append((startPoint, endPoint))\n",
    "            startPoint = None\n",
    "            endPoint = None\n",
    "\n",
    "    # 剔除一些噪点\n",
    "    for point in extrackPoints:\n",
    "        if point[1] - point[0] < min_rect:\n",
    "            extrackPoints.remove(point)\n",
    "    return extrackPoints\n",
    "\n",
    "# 寻找边缘，返回边框的左上角和右下角（利用直方图寻找边缘算法（需行对齐））\n",
    "def findBorderHistogram(path):\n",
    "    borders = []\n",
    "    img = cv2.imread(path, cv2.IMREAD_GRAYSCALE)\n",
    "    img = accessBinary(img)\n",
    "    # 行扫描\n",
    "    hori_vals = np.sum(img, axis=1)\n",
    "    hori_points = extractPeek(hori_vals)\n",
    "    # 根据每一行来扫描列\n",
    "    for hori_point in hori_points:\n",
    "        extractImg = img[hori_point[0]:hori_point[1], :]\n",
    "        vec_vals = np.sum(extractImg, axis=0)\n",
    "        vec_points = extractPeek(vec_vals, min_rect=0)\n",
    "        for vect_point in vec_points:\n",
    "            border = [(vect_point[0], hori_point[0]), (vect_point[1], hori_point[1])]\n",
    "            borders.append(border)\n",
    "    return borders\n",
    "    \n",
    "path = './data/HandWrite/HW_Chinese/test_data/0.png'\n",
    "borders = findBorderHistogram(path)\n",
    "showResults(path, borders)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(32, 280, 3)\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[  510  1275  4590  6120  8415  8415 15300 16575 22695 22695 17595 15555\n",
      " 19125 19890 21165 22440 26520 27285 28560 29325 25755 26010 30345 31875\n",
      " 29835 28815 24735 23970 21930 21165 22440 22695 28305 26775 24735 23205\n",
      " 19125 18615 19890 19890 19380 17595 13770 12495 14280 15810 17085 17850\n",
      " 24480 24225 15810 12240  4335  4590  3825  3060  1020     0     0     0\n",
      "     0     0     0     0]\n",
      "1275\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAABJCAYAAAAkG33uAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAq80lEQVR4nO2dd1yV1RvAv+cOLlyGskE2CO69QFvaUis1c5TbyplaplaWZbZTMytzVFqappmamZqlpqUl7omIIiBuhoMNd5zfH5dABFRk83u/n8/9wHvuO57n3vc+7znPec7zCCklCgoKCgrVD1VlC6CgoKCgcHcoBlxBQUGhmqIYcAUFBYVqimLAFRQUFKopigFXUFBQqKYoBlxBQUGhmlIqAy6E6CyEiBJCRAshXisroRQUFBQUbo+42zhwIYQaOAk8DJwD9gLPSCmPl514CgoKCgrFUZoeeFsgWkoZI6XMAVYA3ctGLAUFBQWF21EaA+4FnL1h+1xum4KCgoJCBaApxbGiiLZC/hghxHBgOIDQWbWyy7YtxSUVypscL1tqOaTnbV+/bovVxQxQUi6UDFsbAoISiY1xxaxR4e2TgADOx7hAemZlS1cuCGsd1gHZXMvUY302G2kyFdzB1gaRlY00mStHwBJiDrbCkKFFd6Hy7/9UriZJKV1vbi+NAT8H+Nyw7Q1cuHknKeVXwFcAukAv2S6ufSkuqVDeqA2uME/LxnobAbhqymDA/c9ijImrXMFuRqXm4vh2pDbOxjpWh+97u8Fsuv1xFYDQaDj5cSsOPrWA+de8CNZdwkfjzOM/TKTDVxcwxp6pbBHLh2ZN+H3t9wB0ONIf9XwXbNbuQRPoz4l3HNl9/xza/DGJkOf2VbKgd4b66zr8EvIrTb6Zgt/UfytVli1yVZE3TWkM+F4gWAgRAJwHngb6leJ8RZLSLxSjTuC0eE+V+YGWFal9Q6kVcQ3zsROVLUoepsRE1L2d6bzyMTbV31DZ4hRL/JR2/DtsJo5qPWnmLJrUGUfd5QZUfx0s92tn9GyH7dkM5N6jgMVgJw9sg8na8v7VFkYiun7B1MQWrI9vxJWLtWg47TwBF8IxllFPztipFVbhkST2b4a5iF+x8/GsCvksimNJgyUM0E/ErmEI0f2dOd1pHqvTPCGnYiOXVba2JPRvivvqKEzJV4rdT4Y1I6m5Ho/NlzBFx+a1a4Uarw7nKkLUu+KuDbiU0iiEGAP8DqiBRVLKiDKTLJd+b/zGvfqTvL7zGUynYsr69OWC2tkJ6eMBZjPmY6dQWesgxB/V1VSMZ86CSo2qcTB93trEokVd8TxW2RIXxJSUTPKyMHgXDufYgcFY2SIVIvjBGH5N9wXAQ3Od2G5fsfZBO+YM74N624FyvbbPhJPs31Yf/70gdDpOv9uSg/0+xU5lzf7sHLKkhvUZruztXR+XkydxAUrzCWr8fYnv7U3taBN2samcfbQ2s4Z9zU/JbVnnPQetUBc6Zl26nvHhfQn5JLvIcwqDCVNEVCmkKp5+sR25+E4QDn/sJvatMKKGzuWPDC1fju5NyJY95XLN4jA1D+b3N2fS7foEav8Rhenq1SL3i3nKhuh+8+jV7yHSOmqQxqp3zxdFaXrgSCk3AhvLSJZicVIbuNbSDfubDLja1ZXrHYOwX7Ov0Aee3qsdqT5qPGbvqnD/1fmB9TkwaQ4nDNlMatONqDeC2PXUJzw2dSJOi86idnZi9q8LCdLY8G0Vdgceys7m7bFj0J3dW9miFCL7gcssy/XgqRs+yL7lh5jkfJwl086Svq38rivbN6OP22r2qesjtFaYW9XncL/PABVbM9W8P2o0V+pZMWjEJkwnT5fJNU9Pr0VEhzmYkWTIHNQIVKi4x2sbBgkGaRmZjj3XiR1xgRy65xsessnhaMcFGDqa0KJGJ/J/6mYkq9Nc+K5xMNKQU2J5NH4+nHjJi3ofxWBKSCz0+2pbO5Y/zrmROCSUzc9NZ3umAx+NHIR2y/7SfRB3QUJLPXqhZcesubSb+gLO3+y65f6DPP5lrmhcoM1gUhdpKIXG0lqZxr5UBryieO3sEzisPVhohjT68zr81n4mPfsNw6NHZF67JtCfOTM+x1tjpPu5l7H7aXeFySo0GlLqG1ELFU8uf5mApHB63pdEqlni+ms0JiCjtT+1VdB8zwB8vo2gqjqGDmX7oPutivorbzAapogo/ukSxI99HsR9dzqCxHK7bHJjPT1s02jYbyanejuTbIwhbOZLeP2WgMgxoI3dhwgp23megPcMJKzPoNPuUQRMucUE6JXrBKVH08unoCfz7BNu1OkSn7d98lQdGk5PQBri7kqexLnWnGw+l+3dtLw79ll0Gws+4F9yjGPuwC74tD7P8RxHPnhxCLotldMJ8Fp/nuxXjOhVVkWHXdyGDHMOundrFWqX7Zvx6Fc7iEirw7mw9Eqb5KwWBvzE0vq4Zu9Cpddz6t2m+DWzzJV+FfA9QVo7gpySSL9hf6nVEKIV6FW2GG0q2Ofm78PGzrNZkepF3e+Twd6eWpoEXNRqzg8IxnNuCimjUnBT2+L+uTWma9crVL47QePpQeDQk5UtRokwnr+Ax6eF5tBLhdBoOPtKWzw6WXygZikI1lvcDj32jsDuV3t0qWY81vyb/xAWghwHeNL+CBu25BvS9G/rUGtZ+F3JIaNieXLyRAJ+P4UpKfn2B0RFF9isExUNM/O3QzhXKpcOP7kQ3ziDB23seNVTgy63WRjMxBrSCNDacXLQPE4a0um8bRzBG6reCK4kaBPT8r5fla0tJ2Y0YmqntQxxSOA7TRrLKzF6umrnQhGWR6bomkzsR2FEfxNC1NNz2dpwHaN9t3Myx+OWh69IdaT2ibSKkDSPE1OcaGClJyrLExkTz7klXkx2Pk7348/gtfAYhnsas7fVcgCkECAEpo4tufRi1YnOiXzdj5WBWzHJqn17FIfa2Ym498NIHBmWdw/dDWcnteXAC5+xteE6rmVacybSg4sf1WVtuh2mE/Y4Lt6Ffk3+6C5hTHtOz2jH+hHTCdDa4WV7jeX1lvNO4Fpsku9+nCWzs6m1LPzOjHcF4PjdLvq+NYl4Yxqz3phHzqOtAZAHI+gzbRIXjWnsz87h+XHjCXn+cCVLW3Zkdm/L2e/9ie4+nyEOCZUtDlBFe+BqV1dS7wnkfCcYVGs2Y1udgVYQmZPB0PjOmKWKi1OCyJh0jeHNVhd7nqUXQ2HP0QqUHFBZhlIBugR+63Uf61vOpOOxgdgNSEO4OHGprQ61sBjGFxcsJ9HoQCPdPupqs+jgNpGAqXsrfwJFBfuzc/jm3R44yMK9RrWDA6kPNijUbr8zBlNi+bkvbkloUzI8bbhSX82bQ5bT224LCaYMZg2/l6PPNUIeLNn8uvn+Fvg8fIZh8Q+y41g9GkyIwiXFMipZ+VqbQvsbHmqF51NxNLFOY2N6A6yFgeSeeu4dPRGHGHDadGvfa3XDcUk4nb1f4fgLczk72EjQ9aaoj8ehzZBcM6sYf7IvNr/syXd7qtRkd2mJycpy79uey4/iqcqoheBSR1dU97my4PXPaKWz4uPkejSwPk8324zKFq9qGvD00AB2fLkgd8uGeGMafY4NQbPIGdtVlh6Phv0wKajI480ONgDoNTmke9UBlYrI99yoVTsDNjvhufzELUOKyoJBDkkMmj4fsEPziTOmpDjiRwcTOWIu54xpJJm0PKo3oCGNCIOBc0YNbzz1EytmNCpTt4ra2QmZY8Ccmlqi416MehqHFXvReHpgvHQZtbMTQqfjWgdf7EeeZUf9BYWOafDPQHx7V5wBVzs6IvQ2ZDTxYvwXy+hmm0GaOYtog+BoDtir4AP3fTToF0pQCSPqVH8dRHaCy0AIe287T6Hdsh/TFsv+Gxq150pzRxyvH6HJA6dI+jfgLjW8c9SOjlzuXZ9rDSQhkw9hzsoq3wtKif+aRMY92Ybwe7+kl0t/+LQeOz6ZS9+YbtgPN2IENB7uoFYTO8SfXaM+oZbK8tts+O8AfHqVr4glJc2cxYSfRxFozO+06ISWA2/NwyBNRORIBsQ9wNUBtVkwoRP3d5/Nh6uewl9W3sO5ShrwG9maqebdMeOp/ecRZHZ0sfupa9fizKhGSDX07LUDvcqKZQF/cDXcciM7q2xQCxUZrXLo1LUftbqWvQHXeHvRMaSg7/jLaz5Yn0vh6tPtWP/sdMKzbHjl5Zex3RpJh38S2ZkUhOoZAzLDMjllTi1bn3jSEmeuRDoTNLHk/ldV03p8+svXPLZ8IsMf/4PBtY6gE6q8H+HNzGu5jPfvGYRq56FSSn17El5oz71D9zLFfT1aBI5qPdMSG7JizQP4z7L07IzN63K6rxX13j5CWQf7uLS+jNrBAVNKSqH3TBFR1IoAUbsWU7w38JIYU8ZXL0z8wjqEt/0UndASFjHmttEWZYEp8hSn7tPzyOCJrH5tBvZfCQafeYzMPhqMF8+S/lQ7Zs2cg78mBzuhRV/MfVMRbMrQ4Xiy6Iea2tGRgBbnGXC6O4Gv7SlyQrJ5+CD8njuHzMpC2KfTvEkMPSKfxv+tig2LvJkqacBtd0TRNaorG+tt5M3Xh2H/W3ihCBTDI61Z3PAzwJZP/H7ml38aM7b2tjz3BECsMYven07C7aDFOCaMz+Jw2+Usa/Qdvca8gtucsl1dlbhAz1qfdQRuGUbQQknaaylcSbHF//gRkqY0J0hrx9Nvj8J5/V7iprRlseMMVi7uhOfl8lnlld21DUsbz6Zz9IS7Ol4KQZDGhlOD5gFgkjY0+HsofvML+8bjulpzauA84r9Zz4p7W5SpK0VorYh9uxUDn8iPDxzpOAMXtS3bM+2ZPGU4dhey0Z6/hm/0v3nGWrXjIME7KHPjDfBnkx9p/tKL+L5T/HcX/VpDGlhtwXriBWQ5B9vqtAb2ZeuZPGU4bn+errDIJnNGBm5f76VT2xf5uMMqrvavRXY9Z9IW2vF5gzm01WmZf82f2au64bM1i45f/MvrLuUTf14cBiTvvTYE2792own0x+Rkh9yXv/givUMwf9T/kqdOdctbLHh5XHtWB04H7Ggc3h+/4RfzRsbpjzfj16B53H+0F1aVvLiwShpwc1o6VzLcALA/U7SfyTommWXX2jLNNYL1aY34ZklXvsl9r1//rbzuEsXzJwbgMTv/B+Z1zImHVz7B5ga/MnncMhbNDy5Tf3OoexwXTZk0ePUC0sGOfr77mH2gU4F9HM7koHJ0ZP3Q6bip7crs2oUQgqTnMwjRljD3jBBIrZnxgVv46N3OeQ/Ef7LMjJw3hqD5Rwu5Y5JGhNHu3ki2ZqqZ+XUfvNIPlZESgErNmcmtOTh4tiUUDLhuzqTViglYJ6pwPWzAYVM4Gh9vIt93o8FbJoxx8bc5acnI6dyGc4MMeduveHzPvYf64f/p0byHg9BaEfNOK6SfpbMgztjgvsdMYr9sYsJ9CeB8mcp0I0KjwUpjYujW5whZHl6xYalCcGlUW3Y/NINkk+D0xw7sDPuCWiprWu0dhHmXI34rz+MXaxkRXMpxKDdR0nu143LPgguXbPTZ1FJZkTP0Cpd7NqdH/cM87HCM6c8PRL3dsuBL9eJldEKLlcqI2dGRhF71WTdxOr4aOzLMOfhOzi7gcnUZG1ego1iZVEkDnvVwC/5s9gVgXew+puhY/rhQn2muEWxLDsHr43xDvfmh+kxwPobNVPuCxyRfIeZoCDSAj050xtVU9qFyUy90QWZmklOvDt3tI9g0tQV41eGewLJZ1HHHCBWTG20q8WEJo8LY28XSu23eZBFN9wxjS6tviMgOps7MXZhvGl6mPBNKwIBTLPXfzqwrgXh+8m+Z9nhVDYMx1s+gdfizeW3afxwI+iw/94kmwA+35VdY57OOBhdeoO4Sa0zHS//dpvUJJcVXxexRC/DXXKfbvhFIKdAKE9cPuuDiq+LSI84ApDbPIvKhz5lyuS0bYhrhtTEL7dEYkkxa6uwo30np2Klt2N/kU5qcHVuu1ymASk3SsLak+sG/Ay33yzVzOmq1mft2jyAzQU/9iccwZ0SWLmSxBJjVgg0dviyi06JlT4uf8ra2ZqqRqsLRSUsDN3DukAEn1XpccjtXHyS1QqRUbCRbSaiSBlxqBHYqaw5lZ6PKNJTIIKgdHfHUp9D832fxPxJd4FhTx5Z88thSRpwLw3P4tTLLS4EQXHopjPmu03nsq1fwufYviS9lYpIg0zNIfiSIDb7ziMjJRJOR35N7OrYTbvuzkGHNUKdmV0hOFKHRkLreF+1nzuh+Kxifq3Z2ImzoAVzUtsQa0ug14xW8vjnAvN1tGOW0l1lv98B3UzrqTAPmw5FcHhvG6gnT8dfo+eq6N8s+fxQXytb3aj52gsDbZNhJaeHBBt9fABV/9ptBn4MTsS9lWZGkEWEsnfwJ1806wjODmDhvBN65Lrf5/3Tkgz7LuPaUnp52MSxOaQhA/5guZAy1xyc6d3heu/ACkPJgTM+NaIUabVLF/JwNj7Sm4ftHWe1pSR/wT5YNS1P8WTKnC97z8r//4n63CaZ06nxpVeZy2f8Yzqhhz3Bhpzc5tcxMf+wHuuiT+DYlCINUE53hzpH3m2F9ORvNrsKrQvUqK1ZeacrvU+/nobd3MNX1OCu2diDoYuH5I5M0cyGhNsFlrkXJqJIG3Ky1PB2f/GMMIYdLsAhACKLn+nIyYDGB+0ZizijoftG8eZketml8ccYVzaWyG2arazmweNynHM1xw2unZQjd0edU3vv3jbfcAN12jqZu+EFwtWSFvPxuEAljM4gIW8awsx2Ib1dmIhWLsLLi1aBNfOA0KG8BBgAqNfFfe7LRaxlXTRn0nGGZIzADaxc8wNQpxzkxbC4MgyM5WfTY/gLhD87AWaUn9ODTuDxzEZfUyg2VyzDn8Oi8V/BZsw80d5/PQuh0vD9pEYlmPVNHPY/V7/tww2K8jZ1a0d99GQ/ZpJJhvsS8qy34q5k+d+IrKfdV8TT+axhBb+0tnM+5HNC/fp45Xru5bpYEbR2K/3cqNFv343qHD+9rZtBFni+XnrnmoXh8sfy2Z+94BteZC1jfxhdzejqQjQ35k44qvR5T82Ce910PwIwrQfwzsAX6o/tY0a8Vj9ofxXtr0Q6pZHMm9d+5WumrqKukAW/x+gEOZWfT8L2LJfuShYqpLdcX+ZYm0J/WzqcwSTNxR+tQl7L1kwJ89OYg7P/Kf1rbqgTnn6nL0/oDjD4fSv03kgro89n8L6ijNgG2RH3QqMDNVV7EvN6MLvodfHBTu7l9E5a2WADoaLV2PMFzLeGaKmtrxoxdA1hu8EvZtfjE8wCRD8/n8RNPc/qsG/XHncJUwjDFsibJlM798ybhM2MPMUsbotMZ8Xn2YrHJi+6Elz8chfPv+UZJZW1Nvy838Jg+i6CVY6k/+4Il0ZcsegVoZrtgnNTll9FRZW1NUr8WBOsWYb/DpsLWDxgnONFyal/cpmoIiYwsccji4z9MJODy3a1KvSuKGGlrAvwYu3kTfpotNLDSM/uqP38OaIf58HGERsOHzX9m9IwxuG4s+qEUuvZlgmMqP81E1fDE38CVoWFMdNtGDirMN8VDa7zq3NE5sqUBq+v5Pi6NVx1sl6QyzTWCpuEDCZlStgsIpMnMUztHUnurxc+d1ieU0S5/4aa25fArc+lud5bwRS0smQiB0y/VxVujw0dtpt2qCbQfPxK7ncWHSN4VZhPvrugLwNuPrkIT4AeAUS/RCjUuw86AypLFThPgx8Bv1tNcp2PGlSDqfX29QOre6yY9AN+sfYQTvXxoP34knV4ag7prAsFD9hcZSlfRHDfY4jv7ENJoxHeBhlo2WUR+UvQ6gdtilhzI8KfzCzstqzn/a87OZvHkbryXVB9NmsAYF4/xfNHG2/hgK8bP+QFfTflNVKtcXdgwbSad9UVnHCwv5P4IXLtFIQ9GYM7KQuPnQ8pvQdj+7Zr3Su0bitrFucBxakdHHLUZaNJEpRdIMF9OZNS2QfjlJqT6fEtnzIcsfje1hzt6kY1VSmEZs7u24W3fdajTVWR3aUn8T01Ktdq3tFQ5A57mI/DV2GG+aRl31uNtafjrRWRYs9ue4/eMWgR8YFm5oXZ1xX5lFisDt3IkJwunpXa5w6myQePnQ/Sbjak3Noazg4OJnh2K1bCLBSZSZiW3xnW+pcehDgmi3+N/oRNa2qx8mbov78b+x/ByWVgUsOYq86950df+ImZbSwxunZ2Sk4Z0htb5B5E7kWO2taGn3TkCNgyz9EKO5PvizVlZLJ3zaN62MfYM9j+GY/fTbmR2xRqO2yE0Gs6+2Z7T/dT80XgFH3ZYTdy7YXkPqjtFGnL4eXYn3nM7Sqr/jW9IbNbu4XiqZ6FjzPe2IHp2aN6ryfTD7EitVzqF7gCTlARueRaXQxZ3obpRPYsMn4becYenNGi8vfBblcjOpj8RedmDOjYprKm7mR2z5qJZrSX5OcsDUOh0XPzOnWmuZZ5xungkZJm1Rb5lzsig3qiDrEt3L9CudnXF/sdMHtHnz1WJ1o2Jf7s9QmvFhYE5NNfpEBLSPDS82uT3clXhdlQ5Aw4QkZPJmA/GYE5LQ+PhTtKIMD7+fB4zPA6S3FRf/IHSzHtHuvLBtEH5wzqX2izy28SebAMjJr+E/ueyzUxo8HJi29MzMDYKYOSzv3K6z3y2NfqlCNkk6pAgGiyPZaqr5Unvvz6nXHsi5sORzPztCZ482R1Vbhkv23X7OZ7jzsLz9yDN+dfOkiYazLiS1wvJQ6UmJbjql1NrpzNw+mt/Zg1eSOxjX7M+w5UfLrXDusk1hLpkBhzAdVUEz8XfgzowDZX+FvccIDs0Z9jCNWzrOZNGLeJo1CKO8E9bc+CKzy2PKyuC5xoRuyw5RwyONnzbbT4n+8wlvp8/Gn/fcr221Ftzn0MUXU90w39IDLG93Qk91IvR5zuwLngThieuAaCysebbpovLVZabsfvjGLO7dis0F/Yf0iwxoSLJlI59bK4pzLUXN3KlkT0LBs3lSr9WLA/9msdPdqHubMto20ebTGrfdre9R8qLKmnAFyV3wH3rBTQBfiQudCD8rTmYEDwXfw/uf14u/kAp8e19lFpLb/CvGU1syazNuDfH4rC8/PxuZq2KyPQ6XDRaQo5WptWixfujWZHqyNHrlp7Q2R7uTHP/lwRT2Y0AbkfQhHBMHQuW8dqVVpeUL33uqMKRylrHNz2+Kk8R7wqNtxeaAD80gf4Ynk9GJ7RsDZvLj0ltaf3mKL4Z3IPs+y/h0SPyrnJem1JSiLjiwdEO33Hq3abF7qcOCaLfwo10srlAl3mvkH3/JbLvv4RDTCZbG64rjYq3ROh0GLydUd80fFftPMTzewahFiqOjp/L5YfLN1Oe6eRppvzal9OXXTCnp2OMi6dW12jOdrGh5b6+pKZU3upLc3p6wZzsKrXlnvG0JMFL6duGUOszhK6cgMdnBX3dV00ZaLItHZf//s6cOo90acX1z3wxXbYks3rQxsSGGbNQebhVgEaFqVKTmNf7h+Jx73mme+wjbcc/ANgJHW0PPIN7/0uYM7OQhpJV5TGdimFek6bUyirfSRPdqUtEt5d0HfYKmyfPIDKzIW5f/svihfWQMoW0PqHYdbxMk3XjsHbNJLLD9+UqT3FIo5HDoTpsc26YjU++Rptfx9PgauwtjqxCCEGHjdG84HQIsNwj54wZ9Jg2CZcl+3E2lE00jPPoHCatbseIRzezbWGrImPLTbX19LKLJ/SLSXhPr7gonMyHm7Fh/ufYiMIGsu6baST9mY6L2par92fh8m35Vpip+9o+EKoCETCm5Cu49UzB7ab2PdkG3A4abj5FhZAwuh2/vzqDIdG9oSPoUkykSw1OR2/wyQuBARNhiybit9ryfdr/uJsP14bmnUefXbnL52+kyvTATQ+0ZMkHn7Ct0S+ohQo1gparxtP1ycG4D03GlJJSqCd1Kc4Zk7x9lHh5J/ZxV9tw/E1vpCEHj++PMjs5/8s2Z2Uhs7NJ6JHFx/VWU29RBiZT5U16gCU96Y2uG+PFS4SM3lN5mQTvAHXdAC5OaE+348l0i0jiBadDfJAYRvPfx6IWKmKMdrguP3xXve3iMMbFsy68FZOcTuP17XmERsO519vzic+vBfZLNRvx+yG+SHdYx4ju2Owsh/j+3Fso5KfRqA4VfLCYY+Pp/9RI+sQ8yNEHFhC1oDkq2xKuyC0B0mgs8nMvqn1LauNCBSDKE9GmCac+b0e348msmTQdN7UtUefdUVlbc66/gaZW+YsFNR7uXJ9lRIuawB+T8r9PKTFnZeW9KnsC9kYqtQduvqc5F1+2PI0DnS8QorXlqimDdksnYB8HwQstqVWLG+g3/PgSp7veokJJBaEVaj7s+BOLm3fBfOg4vy6+l55DthfYRwKD/3qOkH37geKH5FUVgzShzq74B49o0Yhzb8JjARFsdP8ZsIQMtlkykbrLrmD1tGWSavDmYYRklX0tzMCfDDQ7OZoGfU5wcZUv21rNYHOGH34bbp9K9Kopg+yFnlillk8V+uMGNSFvRhTqoEijEfYcJX2gH9PWtOVk5wV0Cx4IN89v1FDOTW6PJgucI3IY9+UKetha3JrbMx3o/tlI6i0+AT51OHTffG5c7S3tbbmyy4PQrMF4X7h9cRC1wbL2wE6lI/pZT/ynxJWTRsVTqQY8eqCW2NDv8rb7xXYkcnkDAuZalknf7jlnPHOWrj9NoGnbCl6mfgOahBRC/h7E7g7zme9pi3WEFZltC/u4a/9pg9sv0Qgfbx4Kql7VbgCWpHjhN+NAuSSGuhXCZGJ8g+08V+sS2zNVPB8+GPt/bQiYuwuTlEAYWzPVBP5oviOffklRbz+Ax3ZI2VSXtDetaf/3GALmSVS7DgGgSUzhi+T2RI/0oe5CDcaYuLxj06UZxx3x5bJg5cI9t5+YNcaeYePy9qxq2oL6yYkV/t1VBkkjwujeZyevu+4hS5pwUVtGHq3298Hhy1p4brJUT1I71S50rOlUDL7vxCKsrDDdQYSV4w97adJyHKf7zMexZeWMXivVgAcvMTCseQdOvdMQ9fjLpH9XB7elJcjMJyUqg2CG388M6TmhQHWUisIUHUvgx41IXGt53AhrHcOa7CTDlL/OUbRujPumeIyJiciwZgx3WQ0F10FWeWqrM1B5umOOLZ/eZHGYj5xgda/7+cHdDm1KNkH78hN7C60VOR5Gvr18L5o/85dGqxrXx+BaMCpAezWrcIRNCTBFRVN3QOF2Y+wZlu9vS+zQedy3Zzg2uQY8JaD8Ju8SR4Wxq99MYoy3X45eZ3ruCtJyk+bOMAd4o1cZWTWv0x2v2CwJanc3/NensMxjJi5qW8KztPyW2orYDGfOTquH298RmDPyO04iK4ctmS70sE0jzVvg+N8bUt5xeKw0GglenIqptxlfh6ukOTqWauHY3XBHPnAhRJwQ4qgQ4pAQYl9um5MQYrMQ4lTuX8fbnafQef85RHy7dHQb9qJ5KL5g9EgJCNLakfXs1bwq0RVN1Ch9Xty3OTWVpQsfLfC+15w4zvaxLKQRuw7z1M6RFS5jaelhe42YQZVT+88UEYXmz/0FUoACxL/SmhNd56JTGVE7OHC9fyjR37dgwOrNbFm2qMBrzKo1mO9pXi7yeW9QE29M43xvizvQ8FArPnrnK1LNKjCXfb8301VYkkeZKid07W6IGqXHXkhqxZTPBKbQahnu8hcGKbloTKPfb6MJb6blclgKVpv2FgolNJ49xxcj+7I/O4dZQxaidnVF7eBQ7Etlb1/kdc3WFpuzMnArV7rWQ2jLPsfLrSiJxesopbwx0cNrwFYp5UdCiNdyt18tU+lKwPv1f2aWuiVUQjmyBm+eoa7dEOpeyijS7XPxcR1eGYfyhrD1p14l9r6qm+GsKL5P9cB/1tEqMwzX+PnwSM896ISWL7z/JPqIGQ/1b7ipi56se0yfxbS6NjjuLHtZbDceomPPsQxouodd7VsT+4zAXZ3G4Lcn4HipfKKfwrNMTJs8ArvUih913g0NJkbx/NRe6JKOlEu+FuP5C7wR1i1vVWT99Mjb5inRbDvEiRxP+tgl4LN3HaZblK0/kOXLp/N6IczgteECxrizJA9tS8cXwvNSyy7/YCaPBbyCz3vlk9+/KErTZe0OPJD7/2JgO5VgwHVXBWnmLNpZZ3LupVYF0spWFKbLCQT1Syj2xry5GK1MTccMZL16DYdjrlU6+uM/Zn7XC6/Uiv9sbyStTyj1X7b0woP0J/MKA1w35/D9lXvZ9UFbVIbC34JUCRpOPoJVWvk8fmR2NnUHHuT3jQ14+bu1dNVf5qtrjXH8rhxcBS7OjOi7kYWJ92H3U8Uab42PNxee8KXloCN5bbvXNqVNj6OobmuWzUAaYAVYsWN7EwJeK8PPR0qMl26xRqRIkUwsHPskf78XwQLvW8vS1CqBIa/OBWDGiCBOpnuw0mtWgepUAVo7TNYVG6FypwZcAn8IISSwQEr5FeAupbwIIKW8KISolEj2OjN20SRwHNFPzKdT772cXuKB8eKlyhClxOxsuoamA0fjOavqG/Dapyon71r82+3J8rCMqlY9+jmtdJYhaoY5h2Z7BpN5vDZ2Z8F13i5sKd6gxf3MLd8vC5yHZzJldD+mANZJAk/K/oEndDr62h/jrbSKdWddmNieB5/ZwwbPm5LFjbv1kMYgTWRLA10jnuHSfo+8dudjVSMUT/vHPg54hxFSt/lt95UqWNH3M0bVjoDaEYDg7yx4/sdR/Pf88v67YmPc79SAd5BSXsg10puFEHcc2CqEGA4MB1C7lEN+ZCmp//Ix6ppHcqL7l9zTZRxOiyrPgAuNhpQGBhrYnGd3o86YIoooH5WdzWeJHfm8zl5uMWqrEkiDkVEH+uNzqXLyngx5ajOvOp9iRaojE071yWvXfOhEnX2nMKdGVopcRWE8d56A18uv8k5lkulp5lCyNw8ke5fouPMHPQn++hJ2SVcIuFY1F4o5LdqF0x3u+9b8XkhNfgSQMBgJOFPFixpLacmXKaVMEEL8DLQFLgshPHN7355AQjHHfgV8BaAL9JIkF7VX6TBnZNBw+iUOd4H5b37GaOOLOP8WXSmuCZVez4f3r6Kr/jIfdnTGrYjcPaaUFHZ8256/J+zl4X7hRGxvBMeiq1xyKLAkdvLtXbbZG0vCriuBfKHKYd3oTuj+urG0fFyV8cdXBrW1GZwvpqhyeRA04e58+YHEVXrO7LKkrMv1lZbbRqEIIWyFEPb//Q88AhwD1gGDc3cbDBSRwaniMMbFM2HCGNRItn3wGVGT7zKVaCkxpaTw9aietJv7Mm5fFv9kdpu7i6mjhzHdYx9rfvkWU9uGFShl9SHrwWQ2NHNFVcB4/39jAj5y38/FAY0rWxSFSkbI2ywLFUIEAj/nbmqAH6SU7wshnIGVgC8QD/SWUt4yJ6pDPXfZqPmk0ktdvLCk+qgwa0F3VWJ9pWr30YzWKtqMO0CmSUvEnMaos6uGX1Ch6iLVguz+V3gx+E++mN4bq9SqfY8rlA3hKyftl1K2vrn9tga8LNG7+ch6T42vsOspKCgo1AQOzZ9QpAGv0JUvmsR0XBZUbt1EBQUFhZpClclGqKCgoKBQMhQDrqCgoFBNqVAfuBAiFSgiMLrG4gIk3XavmoOib83l/0lXqHr6+kkpXW9urOjsT1FFOeJrKkKIfYq+NZf/J33/n3SF6qOv4kJRUFBQqKYoBlxBQUGhmlLRBrzqlTcvXxR9azb/T/r+P+kK1UTfCp3EVFBQUFAoOxQXioKCgkI1pcIMuBCisxAiSggRnVvBp9ojhFgkhEgQQhy7oa3YUnNCiMm5+kcJIR4t+qxVEyGEjxBimxAiUggRIYR4Mbe9puprLYTYI4Q4nKvvtNz2GqkvgBBCLYQ4KIRYn7tdk3UtUZnIKquvlLLcX4AaOA0EYinJcRhoWBHXLme97gNaAsduaJsOvJb7/2vAx7n/N8zVWwcE5H4e6srWoQS6egItc/+3B07m6lRT9RWAXe7/WmA3EFpT9c3V4WXgB2B97nZN1jUOcLmprdrpW1E98LZAtJQyRkqZA6zAUpKtWiOl/Bu4OQNjdywl5sj92+OG9hVSymwpZSwQjeVzqRZIKS9KKQ/k/p8KRAJe1Fx9pZTyv8Kl2tyXpIbqK4TwBh4DvrmhuUbqeguqnb4VZcC9gLM3bJ/LbauJFCg1B/xXaq7GfAZCCH+gBZZeaY3VN9elcAhLsZLNUsqarO9s4BUoUCejpuoK+WUi9+dWDYNqqG9FrcQsqnDY/1v4S434DIQQdsBq4CUpZYoQxdaEq/b6SilNQHMhRG3gZyHErSooVFt9hRCPAwlSyv1CiAfu5JAi2qqFrjdQkjKRVVbfiuqBnwN8btj2Bi5U0LUrmsu5Jea4qdRctf8MhBBaLMZ7mZRyTW5zjdX3P6SU14DtQGdqpr4dgG5CiDgs7s1OQoil1ExdgYJlIrEUrMkrEwnVR9+KMuB7gWAhRIAQwgp4GktJtppIcaXm1gFPCyF0QogAIBjYUwny3RXC0tVeCERKKWfd8FZN1dc1t+eNEMIGeAg4QQ3UV0o5WUrpLaX0x/Lb/FNKOYAaqCvcVZnIqqtvBc76dsUSuXAaeKOyZ2/LSKflwEXAgOUp/RzgDGwFTuX+dbph/zdy9Y8CulS2/CXU9R4sw8YjwKHcV9carG9T4GCuvseAt3Lba6S+N+jwAPlRKDVSVyzRcIdzXxH/2aPqqK+yElNBQUGhmqKsxFRQUFCopigGXEFBQaGaohhwBQUFhWqKYsAVFBQUqimKAVdQUFCopigGXEFBQaGaohhwBQUFhWqKYsAVFBQUqin/Ay6fwcnBBBQGAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[(7, 60), (90, 122), (154, 159), (163, 167), (172, 204), (236, 268), (286, 323), (345, 381), (400, 434), (468, 487), (488, 524)]]\n",
      "[[(7, 60), (90, 122), (154, 204), (236, 268), (286, 323), (345, 381), (400, 434), (468, 524)]]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    " \n",
    "#base_dir = \"/root/workspace/deep_ocr\"\n",
    "#path_test_image = \"test_data.png\"\n",
    "def pepper(img, n):\n",
    "    for k in range(n):\n",
    "        i = int(np.random.random() * img.shape[1])\n",
    "        j = int(np.random.random() * img.shape[0])\n",
    "        if img.ndim == 2:\n",
    "            img[j, i] == 0\n",
    "        elif img.ndim == 3:\n",
    "            img[j,i,0]= 0    \n",
    "            img[j,i,1]= 0    \n",
    "            img[j,i,2]= 0\n",
    "    return img \n",
    "\n",
    "path_test_image = './data/HandWrite/HW_Chinese/test_data/200.png'\n",
    "image_color = cv2.imread(path_test_image)\n",
    "print(image_color.shape)\n",
    "new_shape = (image_color.shape[1] * 2, image_color.shape[0] * 2)\n",
    "image_color = cv2.resize(image_color, new_shape)\n",
    "#image_color = cv2.resize(image_color, (284,216))\n",
    "image = cv2.cvtColor(image_color, cv2.COLOR_BGR2GRAY)\n",
    "#image=np.rot90(image)\n",
    "#erzhihua\n",
    "adaptive_threshold = cv2.adaptiveThreshold(\n",
    "    image,\n",
    "    255,\n",
    "    cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\\\n",
    "    cv2.THRESH_BINARY_INV, 11, 2)\n",
    "adaptive_threshold = pepper(adaptive_threshold, 500)\n",
    "\n",
    "adaptive_threshold1=cv2.medianBlur(adaptive_threshold,3)\n",
    "adaptive_threshold2=cv2.medianBlur(adaptive_threshold,5)\n",
    "\n",
    "#adaptive_threshold3=cv2.medianBlur(adaptive_threshold,7)\n",
    "adaptive_threshold3=adaptive_threshold\n",
    "plt.imshow(adaptive_threshold3)\n",
    "plt.show()\n",
    "#cv2.imshow('yuan1', adaptive_threshold3)\n",
    "#\n",
    "#cv2.imshow('Media3', adaptive_threshold1)\n",
    "#cv2.imshow('media5', adaptive_threshold2)\n",
    "#cv2.imshow('media7', adaptive_threshold3)\n",
    "#\n",
    "#\n",
    "#cv2.waitKey(0)\n",
    "\n",
    "\n",
    "horizontal_sum = np.sum(adaptive_threshold3, axis=1)\n",
    " \n",
    "#plt.plot(horizontal_sum, range(horizontal_sum.shape[0]))\n",
    "#plt.gca().invert_yaxis()\n",
    "#plt.show()\n",
    "print(horizontal_sum)\n",
    "print(horizontal_sum[1])\n",
    "def extract_peek_ranges_from_array(array_vals, minimun_val=230, minimun_range=2):\n",
    "    start_i = None\n",
    "    end_i = None\n",
    "    peek_ranges = []\n",
    "    for i, val in enumerate(array_vals):\n",
    "#        print(\"val\")\n",
    "#        print(val)\n",
    "#        print(\"***************************i*****************************8\")\n",
    "#        print(i)\n",
    "        if val > minimun_val and start_i is None:\n",
    "            start_i = i\n",
    "        elif val > minimun_val and start_i is not None:\n",
    "            pass\n",
    "        elif val < minimun_val and start_i is not None:\n",
    "            end_i = i\n",
    "            if end_i - start_i >= minimun_range:\n",
    "                peek_ranges.append((start_i, end_i))\n",
    "            start_i = None\n",
    "            end_i = None\n",
    "        elif val < minimun_val and start_i is None:\n",
    "            pass\n",
    "        else:\n",
    "            raise ValueError(\"cannot parse this case...\")\n",
    "    return peek_ranges\n",
    "\n",
    "peek_ranges = extract_peek_ranges_from_array(horizontal_sum)\n",
    "\n",
    "line_seg_adaptive_threshold = np.copy(adaptive_threshold3)\n",
    "for i, peek_range in enumerate(peek_ranges):\n",
    "    x = 0\n",
    "    y = peek_range[0]\n",
    "    w = line_seg_adaptive_threshold.shape[1]\n",
    "    h = peek_range[1] - y\n",
    "    pt1 = (x, y)\n",
    "    pt2 = (x + w, y + h)\n",
    "    cv2.rectangle(line_seg_adaptive_threshold, pt1, pt2, 255)   #huaxianhanshu(cv2.rectangle)\n",
    "#cv2.imshow('line image2', line_seg_adaptive_threshold)\n",
    "plt.imshow(line_seg_adaptive_threshold)\n",
    "plt.show()\n",
    "\n",
    "vertical_peek_ranges2d = []\n",
    "for peek_range in peek_ranges:\n",
    "    start_y = peek_range[0]\n",
    "    end_y = peek_range[1]\n",
    "    line_img = adaptive_threshold[start_y:end_y, :]\n",
    "    vertical_sum = np.sum(line_img, axis=0)\n",
    "    vertical_peek_ranges = extract_peek_ranges_from_array(\n",
    "        vertical_sum,\n",
    "        minimun_val=40,\n",
    "        minimun_range=1)\n",
    "    vertical_peek_ranges2d.append(vertical_peek_ranges)\n",
    "print(vertical_peek_ranges2d)\n",
    "tmp=[vertical_peek_ranges2d[0][0]]\n",
    "for i in range(1,len(vertical_peek_ranges2d[0])):\n",
    "    if abs(vertical_peek_ranges2d[0][i][0]-vertical_peek_ranges2d[0][i-1][1])>5:\n",
    "        tmp.append(vertical_peek_ranges2d[0][i])\n",
    "    else:\n",
    "        tmp[-1]=(tmp[-1][0],vertical_peek_ranges2d[0][i][1])\n",
    "vertical_peek_ranges2d=[tmp]\n",
    "    \n",
    "print(vertical_peek_ranges2d)\n",
    "## Draw\n",
    "color = (0, 0, 255)\n",
    "for i, peek_range in enumerate(peek_ranges):\n",
    "    for vertical_range in vertical_peek_ranges2d[i]:\n",
    "        x = vertical_range[0]\n",
    "        y = peek_range[0]\n",
    "        w = vertical_range[1] - x\n",
    "        h = peek_range[1] - y\n",
    "        pt1 = (x, y)\n",
    "        pt2 = (x + w, y + h)\n",
    "        cv2.rectangle(image_color, pt1, pt2, color)\n",
    "plt.imshow(image_color)\n",
    "plt.show()\n",
    "\n",
    "\n",
    "# def median_split_ranges(peek_ranges):\n",
    "#     new_peek_ranges = []\n",
    "#     widthes = []\n",
    "#     for peek_range in peek_ranges:\n",
    "#         w = peek_range[1] - peek_range[0] + 1\n",
    "#         widthes.append(w)\n",
    "#     widthes = np.asarray(widthes)\n",
    "#     median_w = np.median(widthes)\n",
    "#     for i, peek_range in enumerate(peek_ranges):\n",
    "#         num_char = int(round(widthes[i]/median_w, 0))\n",
    "#         if num_char > 1:\n",
    "#             char_w = float(widthes[i] / num_char)\n",
    "#             for i in range(num_char):\n",
    "#                 start_point = peek_range[0] + int(i * char_w)\n",
    "#                 end_point = peek_range[0] + int((i + 1) * char_w)\n",
    "#                 new_peek_ranges.append((start_point, end_point))\n",
    "#         else:\n",
    "#             new_peek_ranges.append(peek_range)\n",
    "#     return new_peek_ranges\n",
    "\n",
    "\n",
    "# vertical_peek_ranges2d = []\n",
    "# for peek_range in peek_ranges:\n",
    "#     start_y = peek_range[0]\n",
    "#     end_y = peek_range[1]\n",
    "#     line_img = adaptive_threshold[start_y:end_y, :]\n",
    "#     vertical_sum = np.sum(line_img, axis=0)\n",
    "#     vertical_peek_ranges = extract_peek_ranges_from_array(\n",
    "#         vertical_sum,\n",
    "#         minimun_val=40,\n",
    "#         minimun_range=1)\n",
    "#     vertical_peek_ranges = median_split_ranges(vertical_peek_ranges)\n",
    "#     vertical_peek_ranges2d.append(vertical_peek_ranges)\n",
    "\n",
    "# ## Draw\n",
    "# color = (0, 0, 255)\n",
    "# for i, peek_range in enumerate(peek_ranges):\n",
    "#     for vertical_range in vertical_peek_ranges2d[i]:\n",
    "#         x = vertical_range[0]\n",
    "#         y = peek_range[0]\n",
    "#         w = vertical_range[1] - x\n",
    "#         h = peek_range[1] - y\n",
    "#         pt1 = (x, y)\n",
    "#         pt2 = (x + w, y + h)\n",
    "#         cv2.rectangle(image_color, pt1, pt2, color)\n",
    "# plt.imshow(image_color)\n",
    "# plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "165px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
